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

commitment allowlist managers #44

Draft
wants to merge 17 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
**/node_modules

packages/contracts/generated
packages/contracts/lib/forge-std
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want to include this in the repo - this is a link to the commit used by the submodule

packages/contracts/deployments/hardhat
packages/contracts/deployments/tenderly
packages/contracts/deployments/localhost
Expand Down
89 changes: 62 additions & 27 deletions packages/contracts/contracts/LenderCommitmentForwarder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import "./TellerV2MarketForwarder.sol";

// Interfaces
import "./interfaces/ICollateralManager.sol";

import "./interfaces/allowlist/IAllowlistManager.sol";
import "./interfaces/allowlist/IEnumerableSetAllowlist.sol";
import { Collateral, CollateralType } from "./interfaces/escrow/ICollateralEscrowV1.sol";

import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";
Expand All @@ -14,8 +17,11 @@ import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeab
import { MathUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";




contract LenderCommitmentForwarder is TellerV2MarketForwarder {
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

enum CommitmentCollateralType {
NONE, // no collateral required
Expand Down Expand Up @@ -59,7 +65,9 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
uint256 commitmentCount;

mapping(uint256 => EnumerableSetUpgradeable.AddressSet)
internal commitmentBorrowersList;
internal __commitmentBorrowersList; //DEPRECATED -> moved to manager

mapping(uint256 => address) public commitmentAllowListManagers;

/**
* @notice This event is emitted when a lender's commitment is created.
Expand Down Expand Up @@ -92,6 +100,11 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
uint256 tokenAmount
);

event UpdatedAllowlistManager(
uint256 indexed commitmentId,
address manager
);

/**
* @notice This event is emitted when the allowed borrowers for a commitment is updated.
* @param commitmentId The id of the commitment that was updated.
Expand Down Expand Up @@ -171,12 +184,13 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
/**
* @notice Creates a loan commitment from a lender for a market.
* @param _commitment The new commitment data expressed as a struct
* @param _borrowerAddressList The array of borrowers that are allowed to accept loans using this commitment
* @param borrowerAllowlistManager The address of the allowlist contract
* @return commitmentId_ returns the commitmentId for the created commitment
*/
function createCommitment(
Commitment calldata _commitment,
address[] calldata _borrowerAddressList
// address[] calldata _borrowerAddressList,
address borrowerAllowlistManager
) public returns (uint256 commitmentId_) {
commitmentId_ = commitmentCount++;

Expand All @@ -186,10 +200,11 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
);

commitments[commitmentId_] = _commitment;
commitmentAllowListManagers[commitmentId_] = borrowerAllowlistManager;

validateCommitment(commitments[commitmentId_]);

_addBorrowersToCommitmentAllowlist(commitmentId_, _borrowerAddressList);
//_addBorrowersToCommitmentAllowlist(commitmentId_, _borrowerAddressList);

emit CreatedCommitment(
commitmentId_,
Expand All @@ -198,6 +213,11 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
_commitment.principalTokenAddress,
_commitment.maxPrincipal
);

emit UpdatedAllowlistManager(
commitmentId_,
borrowerAllowlistManager
);
}

/**
Expand Down Expand Up @@ -232,6 +252,20 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
);
}

function updateAllowlistManager(
uint256 _commitmentId,
address _allowlistManager
) public commitmentLender(_commitmentId) {

commitmentAllowListManagers[_commitmentId] = _allowlistManager;

emit UpdatedAllowlistManager(_commitmentId,_allowlistManager);
//emit UpdatedAllowList(_commitmentId);
}


//should be able to set this in one tx

/**
* @notice Updates the borrowers allowed to accept a commitment
* @param _commitmentId The Id of the commitment to update.
Expand All @@ -241,25 +275,15 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
uint256 _commitmentId,
address[] calldata _borrowerAddressList
) public commitmentLender(_commitmentId) {
delete commitmentBorrowersList[_commitmentId];
_addBorrowersToCommitmentAllowlist(_commitmentId, _borrowerAddressList);
}

address allowlistManager = commitmentAllowListManagers[_commitmentId];

/**
* @notice Adds a borrower to the allowlist for a commmitment.
* @param _commitmentId The id of the commitment that will allow the new borrower
* @param _borrowerArray the address array of the borrowers that will be allowed to accept loans using the commitment
*/
function _addBorrowersToCommitmentAllowlist(
uint256 _commitmentId,
address[] calldata _borrowerArray
) internal {
for (uint256 i = 0; i < _borrowerArray.length; i++) {
commitmentBorrowersList[_commitmentId].add(_borrowerArray[i]);
}
emit UpdatedCommitmentBorrowers(_commitmentId);
IEnumerableSetAllowlist(allowlistManager).setAllowlist(_commitmentId, _borrowerAddressList);

//emit UpdatedAllowList(_commitmentId);
}


/**
* @notice Removes the commitment of a lender to a market.
* @param _commitmentId The id of the commitment to delete.
Expand All @@ -269,7 +293,7 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
commitmentLender(_commitmentId)
{
delete commitments[_commitmentId];
delete commitmentBorrowersList[_commitmentId];
//delete commitmentBorrowersList[_commitmentId];
emit DeletedCommitment(_commitmentId);
}

Expand Down Expand Up @@ -326,10 +350,19 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
);

require(
commitmentBorrowersList[_commitmentId].length() == 0 ||
commitmentBorrowersList[_commitmentId].contains(borrower),
"unauthorized commitment borrower"
__commitmentBorrowersList[_commitmentId].length() == 0 ||
commitmentAllowListManagers[_commitmentId] != address(0),
"Commitments with legacy borrower list must now set an allow list manager"
);


require(commitmentAllowListManagers[_commitmentId] == address(0) ||
IAllowlistManager(commitmentAllowListManagers[_commitmentId]).addressIsAllowed(
_commitmentId, borrower
),
"Borrower not allowlisted"
);


if (_principalAmount > commitment.maxPrincipal) {
revert InsufficientCommitmentAllocation({
Expand Down Expand Up @@ -398,6 +431,8 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
);
}



/**
* @notice Calculate the amount of collateral required to borrow a loan with _principalAmount of principal
* @param _principalAmount The amount of currency to borrow for the loan.
Expand Down Expand Up @@ -446,13 +481,13 @@ contract LenderCommitmentForwarder is TellerV2MarketForwarder {
* @param _commitmentId The commitment id for the commitment to query.
* @return borrowers_ An array of addresses restricted to accept the commitment. Empty array means unrestricted.
*/
function getCommitmentBorrowers(uint256 _commitmentId)
/* function getCommitmentBorrowers(uint256 _commitmentId)
external
view
returns (address[] memory borrowers_)
{
borrowers_ = commitmentBorrowersList[_commitmentId].values();
}
}*/

/**
* @notice Internal function to submit a bid to the lending protocol using a commitment
Expand Down
41 changes: 41 additions & 0 deletions packages/contracts/contracts/allowlist/ERC721Allowlist.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

pragma solidity >=0.8.0 <0.9.0;
// SPDX-License-Identifier: MIT
import "../interfaces/allowlist/IAllowlistManager.sol";

import "../interfaces/allowlist/IERC721Allowlist.sol";

import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";

contract ERC721Allowlist is IAllowlistManager,IERC721Allowlist {

event UpdatedAllowList(uint256 commitmentId);

address public immutable authorized;
IERC721Upgradeable public immutable accessToken; //IERC721


modifier onlyAuthorized(){
require(msg.sender == authorized,"Must be authorized.");
_;
}

constructor(address _authorized, address _accessToken){
authorized = _authorized;
accessToken = IERC721Upgradeable(_accessToken);
}

function addressIsAllowed(uint256 _commitmentId, address _account) public virtual returns (bool) {
return accessToken.balanceOf(_account) >= 1;
}

/*
function getAllowedAddresses(uint256 _commitmentId)
public
view
returns (address[] memory borrowers_)
{
borrowers_ = allowList[_commitmentId].values();
}*/

}
68 changes: 68 additions & 0 deletions packages/contracts/contracts/allowlist/EnumerableSetAllowlist.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
pragma solidity >=0.8.0 <0.9.0;
// SPDX-License-Identifier: MIT

import "../interfaces/allowlist/IAllowlistManager.sol";
import "../interfaces/allowlist/IEnumerableSetAllowlist.sol";

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


contract EnumerableSetAllowlist is IAllowlistManager,IEnumerableSetAllowlist {
using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;

event UpdatedAllowList(uint256 commitmentId);

address public immutable authorized;

mapping(uint256 => EnumerableSetUpgradeable.AddressSet) internal allowList;

modifier onlyAuthorized(){
require(msg.sender == authorized,"Must be authorized.");
_;
}

constructor(address _authorized){
authorized = _authorized;
}


function setAllowlist(
uint256 _commitmentId,
address[] calldata _addressList
) public onlyAuthorized {

delete allowList[_commitmentId];
_addToAllowlist(_commitmentId, _addressList);
}


/**
* @notice Adds a addresses to the allowlist for a commmitment.
* @param _commitmentId The id of the commitment that will allow the new borrower
* @param _addressList the address array that will be allowed to accept loans using the commitment
*/
function _addToAllowlist(
uint256 _commitmentId,
address[] calldata _addressList
) internal virtual {

for (uint256 i = 0; i < _addressList.length; i++) {
allowList[_commitmentId].add(_addressList[i]);
}
emit UpdatedAllowList(_commitmentId);
}


function addressIsAllowed(uint256 _commitmentId, address _account) public virtual returns (bool) {
return allowList[_commitmentId].contains(_account);
}

function getAllowedAddresses(uint256 _commitmentId)
public
view
returns (address[] memory borrowers_)
{
borrowers_ = allowList[_commitmentId].values();
}

}
41 changes: 41 additions & 0 deletions packages/contracts/contracts/allowlist/MasaAllowlist.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

pragma solidity >=0.8.0 <0.9.0;
// SPDX-License-Identifier: MIT
import "../interfaces/allowlist/IAllowlistManager.sol";

import "../interfaces/allowlist/IERC721Allowlist.sol";

import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";

contract ERC721Allowlist is IAllowlistManager,IERC721Allowlist {

event UpdatedAllowList(uint256 commitmentId);

address public immutable authorized;
IERC721Upgradeable public immutable accessToken; //IERC721


modifier onlyAuthorized(){
require(msg.sender == authorized,"Must be authorized.");
_;
}

constructor(address _authorized, address _accessToken){
authorized = _authorized;
accessToken = IERC721Upgradeable(_accessToken);
}

function addressIsAllowed(uint256 _commitmentId, address _account) public virtual returns (bool) {
return accessToken.balanceOf(_account) >= 1;
}

/*
function getAllowedAddresses(uint256 _commitmentId)
public
view
returns (address[] memory borrowers_)
{
borrowers_ = allowList[_commitmentId].values();
}*/

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@



interface IAllowlistManager {


function addressIsAllowed(uint256 _commitmentId,address _account) external returns (bool allowed_) ;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


interface IERC721Allowlist {


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@



interface IEnumerableSetAllowlist {

function setAllowlist(
uint256 _commitmentId,
address[] calldata _addressList
) external;

}
Loading