Skip to content
Open
573 changes: 573 additions & 0 deletions packages/contracts/.openzeppelin/polygon.json

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions packages/contracts/.openzeppelin/unknown-747474.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
"address": "0x21499A1Fd9f36ce527CB4A9032072ef1bb7a22F6",
"txHash": "0x4211719c23ad7e3ddbc3aff9c650e0e380facfde12bc2f5caadb0a4aace176a0",
"kind": "transparent"
},
{
"address": "0x128BB34BBe1E9A6Ac07268dfA475459334500E89",
"txHash": "0x26f2bf8fe6a0feff94b753323dfce9ff7a2554c4e2a172dbb81f083decd59396",
"kind": "transparent"
}
],
"impls": {
Expand Down Expand Up @@ -3912,6 +3917,16 @@
"types": {},
"namespaces": {}
}
},
"3ab250b99fe7352d1cf4d7cdd8a432fa925eaff7463e0beabcbe7254268f31a6": {
"address": "0xE9D02C0e0449A396A09A42fE03Ff06300C972Db5",
"txHash": "0xa811576aee77e565764eeafacbcdc2273f580ffe1bd13c850bfa1ab0c1c5c0a8",
"layout": {
"solcVersion": "0.8.11",
"storage": [],
"types": {},
"namespaces": {}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,16 @@ contract LenderCommitmentGroupFactory_V2 is OwnableUpgradeable {

address sharesRecipient = msg.sender;

//first the shares enter the factory
uint256 sharesAmount_ = IERC4626( address(_newGroupContract) )
.deposit(
_initialPrincipalAmount,
sharesRecipient
address(this)
);

//then they are sent to the caller
IERC20( address(_newGroupContract) ).transfer(
sharesRecipient, sharesAmount_
);

return sharesAmount_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ contract LenderCommitmentGroup_Pool_V2 is


// uint256 immutable public DEFAULT_WITHDRAW_DELAY_TIME_SECONDS = 300;
// uint256 immutable public MAX_WITHDRAW_DELAY_TIME = 86400;
uint256 immutable public MAX_WITHDRAW_DELAY_TIME = 86400;

mapping(uint256 => bool) public activeBids;
mapping(uint256 => uint256) public activeBidsAmountDueRemaining;
Expand All @@ -165,6 +165,8 @@ contract LenderCommitmentGroup_Pool_V2 is

mapping(address => bool) public withdrawDelayBypassForAccount;

mapping(address => mapping(address => bool )) private sharesDelegate;

event PoolInitialized(
address indexed principalTokenAddress,
address indexed collateralTokenAddress,
Expand Down Expand Up @@ -742,32 +744,7 @@ contract LenderCommitmentGroup_Pool_V2 is
return pairPriceWithTwapFromOracle;
}

/**
* @notice Calculates the principal token amount per collateral token based on Uniswap oracle prices
* @dev Uses Uniswap TWAP and applies any configured maximum limits
* @dev Returns the lesser of the oracle price or the configured maximum (if set)
* @param poolOracleRoutes Array of pool route configurations to use for price calculation
* @return The principal per collateral ratio, expanded by the Uniswap expansion factor
*/
function getPrincipalForCollateralForPoolRoutes(
IUniswapPricingLibrary.PoolRouteConfig[] memory poolOracleRoutes
) external view virtual returns (uint256 ) {

uint256 pairPriceWithTwapFromOracle = IUniswapPricingLibrary(UNISWAP_PRICING_HELPER)
.getUniswapPriceRatioForPoolRoutes(poolOracleRoutes);


uint256 principalPerCollateralAmount = maxPrincipalPerCollateralAmount == 0
? pairPriceWithTwapFromOracle
: Math.min(
pairPriceWithTwapFromOracle,
maxPrincipalPerCollateralAmount //this is expanded by uniswap exp factor
);


return principalPerCollateralAmount;
}



/**
* @notice Calculates the amount of collateral tokens required for a given principal amount
Expand Down Expand Up @@ -870,6 +847,13 @@ contract LenderCommitmentGroup_Pool_V2 is
maxPrincipalPerCollateralAmount = _maxPrincipalPerCollateralAmount;
}



function getMaxPrincipalPerCollateralAmount() external view returns (uint256) {

return maxPrincipalPerCollateralAmount;
}




Expand Down Expand Up @@ -1152,6 +1136,33 @@ contract LenderCommitmentGroup_Pool_V2 is



/**
* @notice Sets the delay time for withdrawing shares. Only Protocol Owner.
* @param _seconds Delay time in seconds.
*/
function setWithdrawDelayTime(uint256 _seconds)
external
onlyProtocolOwner {
require( _seconds < MAX_WITHDRAW_DELAY_TIME , "WD");

withdrawDelayTimeSeconds = _seconds;
}



function setSharesDelegate( address delegate, bool approved ) external {

sharesDelegate[ msg.sender ][delegate] = approved;

}

function isSharesDelegate( address owner , address delegate ) public returns (bool) {

return owner == delegate || sharesDelegate[owner][delegate];
}



// ------------------------ Pausing functions ------------


Expand Down Expand Up @@ -1280,6 +1291,9 @@ contract LenderCommitmentGroup_Pool_V2 is






// ------------------------ ERC4626 functions ------------


Expand All @@ -1302,8 +1316,10 @@ contract LenderCommitmentGroup_Pool_V2 is
// Similar to addPrincipalToCommitmentGroup but following ERC4626 standard
require(assets > 0 );

bool poolWasActivated = poolIsActivated();
bool poolWasActivated = poolIsActivated();
require( isSharesDelegate( receiver, msg.sender ) , "UA");



// Transfer assets from sender to vault
uint256 principalTokenBalanceBefore = principalToken.balanceOf(address(this));
Expand Down Expand Up @@ -1351,6 +1367,8 @@ contract LenderCommitmentGroup_Pool_V2 is
assets = previewMint(shares);
require(assets > 0);

require( isSharesDelegate( receiver, msg.sender ) , "UA");


bool poolWasActivated = poolIsActivated();

Expand Down Expand Up @@ -1397,11 +1415,11 @@ contract LenderCommitmentGroup_Pool_V2 is


require(
withdrawDelayBypassForAccount[msg.sender] ||
withdrawDelayBypassForAccount[ owner ] ||
block.timestamp >= sharesLastTransferredAt + withdrawDelayTimeSeconds, "SW"
);

require(msg.sender == owner, "UA");
require(isSharesDelegate( owner, msg.sender ) , "UA");

// Burn shares from owner
burnShares(owner, shares);
Expand Down Expand Up @@ -1440,12 +1458,14 @@ contract LenderCommitmentGroup_Pool_V2 is
// Calculate assets to receive
assets = _valueOfUnderlying(shares, sharesExchangeRateInverse());

require(msg.sender == owner, "UA");

require(isSharesDelegate( owner, msg.sender ) , "UA");


// Check withdrawal delay
uint256 sharesLastTransferredAt = getSharesLastTransferredAt(owner);
require(
withdrawDelayBypassForAccount[msg.sender] ||
withdrawDelayBypassForAccount[ owner ] ||
block.timestamp >= sharesLastTransferredAt + withdrawDelayTimeSeconds, "SR"
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ interface ILenderCommitmentGroup_V2 {

function getTokenDifferenceFromLiquidations() external view returns (int256);

}
function getMaxPrincipalPerCollateralAmount() external view returns (uint256);
}
49 changes: 49 additions & 0 deletions packages/contracts/contracts/libraries/uniswap/BitMath.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title BitMath
/// @dev This library provides functionality for computing bit properties of an unsigned integer
/// @author Solady (https://github.com/Vectorized/solady/blob/8200a70e8dc2a77ecb074fc2e99a2a0d36547522/src/utils/LibBit.sol)
library BitMath {
/// @notice Returns the index of the most significant bit of the number,
/// where the least significant bit is at index 0 and the most significant bit is at index 255
/// @param x the value for which to compute the most significant bit, must be greater than 0
/// @return r the index of the most significant bit
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0);

assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// forgefmt: disable-next-item
r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020500060203020504000106050205030304010505030400000000))
}
}

/// @notice Returns the index of the least significant bit of the number,
/// where the least significant bit is at index 0 and the most significant bit is at index 255
/// @param x the value for which to compute the least significant bit, must be greater than 0
/// @return r the index of the least significant bit
function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0);

assembly {
// Isolate the least significant bit.
x := and(x, sub(0, x))
// For the upper 3 bits of the result, use a De Bruijn-like lookup.
// Credit to adhusson: https://blog.adhusson.com/cheap-find-first-set-evm/
// forgefmt: disable-next-item
r := shl(5, shr(252, shl(shl(2, shr(250, mul(x,
0xb6db6db6ddddddddd34d34d349249249210842108c6318c639ce739cffffffff))),
0x8040405543005266443200005020610674053026020000107506200176117077)))
// For the lower 5 bits of the result, use a De Bruijn lookup.
// forgefmt: disable-next-item
r := or(r, byte(and(div(0xd76453e0, shr(r, x)), 0x1f),
0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
}
}
}
120 changes: 120 additions & 0 deletions packages/contracts/contracts/libraries/uniswap/CustomRevert.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/// @title Library for reverting with custom errors efficiently
/// @notice Contains functions for reverting with custom errors with different argument types efficiently
/// @dev To use this library, declare `using CustomRevert for bytes4;` and replace `revert CustomError()` with
/// `CustomError.selector.revertWith()`
/// @dev The functions may tamper with the free memory pointer but it is fine since the call context is exited immediately
library CustomRevert {
/// @dev ERC-7751 error for wrapping bubbled up reverts
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);

/// @dev Reverts with the selector of a custom error in the scratch space
function revertWith(bytes4 selector) internal pure {
assembly {
mstore(0, selector)
revert(0, 0x04)
}
}

/// @dev Reverts with a custom error with an address argument in the scratch space
function revertWith(bytes4 selector, address addr) internal pure {
assembly {
mstore(0, selector)
mstore(0x04, and(addr, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}

/// @dev Reverts with a custom error with an int24 argument in the scratch space
function revertWith(bytes4 selector, int24 value) internal pure {
assembly {
mstore(0, selector)
mstore(0x04, signextend(2, value))
revert(0, 0x24)
}
}

/// @dev Reverts with a custom error with a uint160 argument in the scratch space
function revertWith(bytes4 selector, uint160 value) internal pure {
assembly {
mstore(0, selector)
mstore(0x04, and(value, 0xffffffffffffffffffffffffffffffffffffffff))
revert(0, 0x24)
}
}

/// @dev Reverts with a custom error with two int24 arguments
function revertWith(bytes4 selector, int24 value1, int24 value2) internal pure {
assembly {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), signextend(2, value1))
mstore(add(fmp, 0x24), signextend(2, value2))
revert(fmp, 0x44)
}
}

/// @dev Reverts with a custom error with two uint160 arguments
function revertWith(bytes4 selector, uint160 value1, uint160 value2) internal pure {
assembly {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(fmp, 0x44)
}
}

/// @dev Reverts with a custom error with two address arguments
function revertWith(bytes4 selector, address value1, address value2) internal pure {
assembly {
let fmp := mload(0x40)
mstore(fmp, selector)
mstore(add(fmp, 0x04), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(fmp, 0x24), and(value2, 0xffffffffffffffffffffffffffffffffffffffff))
revert(fmp, 0x44)
}
}

/// @notice bubble up the revert message returned by a call and revert with a wrapped ERC-7751 error
/// @dev this method can be vulnerable to revert data bombs
function bubbleUpAndRevertWith(
address revertingContract,
bytes4 revertingFunctionSelector,
bytes4 additionalContext
) internal pure {
bytes4 wrappedErrorSelector = WrappedError.selector;
assembly {
// Ensure the size of the revert data is a multiple of 32 bytes
let encodedDataSize := mul(div(add(returndatasize(), 31), 32), 32)

let fmp := mload(0x40)

// Encode wrapped error selector, address, function selector, offset, additional context, size, revert reason
mstore(fmp, wrappedErrorSelector)
mstore(add(fmp, 0x04), and(revertingContract, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(
add(fmp, 0x24),
and(revertingFunctionSelector, 0xffffffff00000000000000000000000000000000000000000000000000000000)
)
// offset revert reason
mstore(add(fmp, 0x44), 0x80)
// offset additional context
mstore(add(fmp, 0x64), add(0xa0, encodedDataSize))
// size revert reason
mstore(add(fmp, 0x84), returndatasize())
// revert reason
returndatacopy(add(fmp, 0xa4), 0, returndatasize())
// size additional context
mstore(add(fmp, add(0xa4, encodedDataSize)), 0x04)
// additional context
mstore(
add(fmp, add(0xc4, encodedDataSize)),
and(additionalContext, 0xffffffff00000000000000000000000000000000000000000000000000000000)
)
revert(fmp, add(0xe4, encodedDataSize))
}
}
}
Loading