Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge train r3 #53

Open
wants to merge 18 commits into
base: merge-train-r2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions packages/contracts/contracts/CollateralManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

// Libraries
import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";

import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
// Interfaces
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
Expand Down Expand Up @@ -70,14 +70,19 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
_;
}

modifier onlyProtocolOwner() {
modifier onlyProtocolOwner() {

address protocolOwner = OwnableUpgradeable(address(tellerV2)).owner();

require(_msgSender() == protocolOwner, "Sender not authorized");
_;
}

modifier whenProtocolNotPaused() {
require( PausableUpgradeable(address(tellerV2)).paused() == false , "Protocol is paused");
_;
}

/* External Functions */

/**
Expand Down Expand Up @@ -262,7 +267,7 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
* @notice Withdraws deposited collateral from the created escrow of a bid that has been successfully repaid.
* @param _bidId The id of the bid to withdraw collateral for.
*/
function withdraw(uint256 _bidId) external {
function withdraw(uint256 _bidId) external whenProtocolNotPaused {
BidState bidState = tellerV2.getBidState(_bidId);

require(bidState == BidState.PAID, "collateral cannot be withdrawn");
Expand All @@ -277,7 +282,7 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
address _tokenAddress,
uint256 _amount,
address _recipientAddress
) external onlyProtocolOwner {
) external onlyProtocolOwner whenProtocolNotPaused {

ICollateralEscrowV1(_escrows[_bidId]).withdrawDustTokens(
_tokenAddress,
Expand All @@ -290,7 +295,7 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
* @notice Withdraws deposited collateral from the created escrow of a bid that has been CLOSED after being defaulted.
* @param _bidId The id of the bid to withdraw collateral for.
*/
function lenderClaimCollateral(uint256 _bidId) external onlyTellerV2 {
function lenderClaimCollateral(uint256 _bidId) external onlyTellerV2 whenProtocolNotPaused {
if (isBidCollateralBacked(_bidId)) {
BidState bidState = tellerV2.getBidState(_bidId);

Expand All @@ -308,7 +313,7 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
* @notice Withdraws deposited collateral from the created escrow of a bid that has been CLOSED after being defaulted.
* @param _bidId The id of the bid to withdraw collateral for.
*/
function lenderClaimCollateralWithRecipient(uint256 _bidId, address _collateralRecipient) external onlyTellerV2 {
function lenderClaimCollateralWithRecipient(uint256 _bidId, address _collateralRecipient) external onlyTellerV2 whenProtocolNotPaused {
if (isBidCollateralBacked(_bidId)) {
BidState bidState = tellerV2.getBidState(_bidId);

Expand All @@ -331,6 +336,7 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
function liquidateCollateral(uint256 _bidId, address _liquidatorAddress)
external
onlyTellerV2
whenProtocolNotPaused
{
if (isBidCollateralBacked(_bidId)) {
BidState bidState = tellerV2.getBidState(_bidId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import "../interfaces/ILenderCommitmentForwarder.sol";
import "../interfaces/ISmartCommitmentForwarder.sol";
import "./LenderCommitmentForwarder_G1.sol";

import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";

import { CommitmentCollateralType, ISmartCommitment } from "../interfaces/ISmartCommitment.sol";


contract SmartCommitmentForwarder is
ExtensionsContextUpgradeable, //this should always be first for upgradeability
ExtensionsContextUpgradeable, //this should always be first for upgradeability
TellerV2MarketForwarder_G3,
PausableUpgradeable, //this does add some storage but AFTER all other storage
ISmartCommitmentForwarder
{
event ExercisedSmartCommitment(
Expand All @@ -24,9 +27,23 @@ contract SmartCommitmentForwarder is

error InsufficientBorrowerCollateral(uint256 required, uint256 actual);



modifier onlyProtocolPauser() {
require( ITellerV2( _tellerV2 ).isPauser(_msgSender()) , "Sender not authorized");
_;
}



constructor(address _protocolAddress, address _marketRegistry)
TellerV2MarketForwarder_G3(_protocolAddress, _marketRegistry)
{}
{ }

function initialize() public initializer {
__Pausable_init();
}


/**
* @notice Accept the commitment to submitBid and acceptBid using the funds
Expand All @@ -50,7 +67,7 @@ contract SmartCommitmentForwarder is
address _recipient,
uint16 _interestRate,
uint32 _loanDuration
) public returns (uint256 bidId) {
) public whenNotPaused returns (uint256 bidId) {
require(
ISmartCommitment(_smartCommitmentAddress)
.getCollateralTokenType() <=
Expand Down Expand Up @@ -162,6 +179,23 @@ contract SmartCommitmentForwarder is



/**
* @notice Lets the DAO/owner of the protocol implement an emergency stop mechanism.
*/
function pause() public virtual onlyProtocolPauser whenNotPaused {
_pause();
}

/**
* @notice Lets the DAO/owner of the protocol undo a previously implemented emergency stop.
*/
function unpause() public virtual onlyProtocolPauser whenPaused {
_unpause();
}


// -----

//Overrides
function _msgSender()
internal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Contracts
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// Interfaces
import "../../../interfaces/ITellerV2.sol";
import "../../../interfaces/IProtocolFee.sol";
import "../../../interfaces/ITellerV2Storage.sol";
//import "../../../interfaces/ILenderCommitmentForwarder.sol";
import "../../../libraries/NumbersLib.sol";

import "./LenderCommitmentGroup_Smart.sol";
//import {CreateCommitmentArgs} from "../../interfaces/ILenderCommitmentGroup.sol";

import { ILenderCommitmentGroup } from "../../../interfaces/ILenderCommitmentGroup.sol";

contract LenderCommitmentGroupFactory {
using AddressUpgradeable for address;
using NumbersLib for uint256;

/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
ITellerV2 public immutable TELLER_V2;
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable SMART_COMMITMENT_FORWARDER;
address public immutable UNISWAP_V3_FACTORY;

mapping(address => uint256) public deployedLenderGroupContracts;

event DeployedLenderGroupContract(address indexed groupContract);

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address _tellerV2,
address _smartCommitmentForwarder,
address _uniswapV3Factory
) {
TELLER_V2 = ITellerV2(_tellerV2);
SMART_COMMITMENT_FORWARDER = _smartCommitmentForwarder;
UNISWAP_V3_FACTORY = _uniswapV3Factory;
}

/*
This should deploy a new lender commitment group pool contract.
It will use create commitment args in order to define the pool contracts parameters such as its primary principal token.
Shares will be distributed at a 1:1 ratio of the primary principal token so if 1e18 raw WETH are deposited, the depositor gets 1e18 shares for the group pool.
*/
function deployLenderCommitmentGroupPool(
uint256 _initialPrincipalAmount,
address _principalTokenAddress,
address _collateralTokenAddress,
uint256 _marketId,
uint32 _maxLoanDuration,
uint16 _interestRateLowerBound,
uint16 _interestRateUpperBound,
uint16 _liquidityThresholdPercent,
uint16 _loanToValuePercent,
uint24 _uniswapPoolFee,
uint32 _twapInterval
) external returns (address newGroupContract_) {
//these should be upgradeable proxies ???
newGroupContract_ = address(
new LenderCommitmentGroup_Smart(
address(TELLER_V2),
address(SMART_COMMITMENT_FORWARDER),
address(UNISWAP_V3_FACTORY)
)
);

deployedLenderGroupContracts[newGroupContract_] = block.number; //consider changing this ?
emit DeployedLenderGroupContract(newGroupContract_);

/*
The max principal should be a very high number! higher than usual
The expiration time should be far in the future! farther than usual
*/
ILenderCommitmentGroup(newGroupContract_).initialize(
_principalTokenAddress,
_collateralTokenAddress,
_marketId,
_maxLoanDuration,
_interestRateLowerBound,
_interestRateUpperBound,
_liquidityThresholdPercent,
_loanToValuePercent,
_uniswapPoolFee,
_twapInterval
);

//it is not absolutely necessary to have this call here but it allows the user to potentially save a tx step so it is nice to have .
if (_initialPrincipalAmount > 0) {
//should pull in the creators initial committed principal tokens .

//send the initial principal tokens to _newgroupcontract here !
// so it will have them for addPrincipalToCommitmentGroup which will pull them from here

IERC20(_principalTokenAddress).transferFrom(
msg.sender,
address(this),
_initialPrincipalAmount
);
IERC20(_principalTokenAddress).approve(
address(newGroupContract_),
_initialPrincipalAmount
);

address sharesRecipient = msg.sender;



uint256 sharesAmount_ = ILenderCommitmentGroup(newGroupContract_)
.addPrincipalToCommitmentGroup(
_initialPrincipalAmount,
sharesRecipient,
0 //_minShares
);
}
}
}
Loading
Loading