Skip to content
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
409 changes: 409 additions & 0 deletions packages/contracts/.openzeppelin/unknown-33139.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,7 @@ yarn contracts test_forked



### Package Version Warning

Please do not install/use published package versions 3.1.52 or 3.1.53 as they are problematic.

Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,10 @@ contract LenderCommitmentGroup_Pool_V3 is

uint256 constant Q96 = 0x1000000000000000000000000;

uint256 public immutable STANDARD_EXPANSION_FACTOR = 1e18;


uint256 public immutable MIN_TWAP_INTERVAL = 3;

uint256 public immutable UNISWAP_EXPANSION_FACTOR = 2**96;

uint256 public immutable EXCHANGE_RATE_EXPANSION_FACTOR = 1e36;

using SafeERC20 for IERC20;
Expand Down Expand Up @@ -159,7 +157,7 @@ contract LenderCommitmentGroup_Pool_V3 is


//configured by the owner. If 0 , not used.
uint256 public maxPrincipalPerCollateralAmount; // DEPRECATED FOR NOW
uint256 public maxPrincipalPerCollateralAmount;


uint256 public lastUnpausedAt;
Expand Down Expand Up @@ -298,7 +296,8 @@ contract LenderCommitmentGroup_Pool_V3 is
) external initializer {

__Ownable_init();

__ReentrancyGuard_init();

__Shares_init(
_commitmentGroupConfig.principalTokenAddress,
_commitmentGroupConfig.collateralTokenAddress
Expand Down Expand Up @@ -705,54 +704,85 @@ contract LenderCommitmentGroup_Pool_V3 is
return baseAmount.percent(collateralRatio);
}

/*
* @dev this is expanded by 10e18
* @dev this logic is very similar to that used in LCFA
/*
* @dev this is expanded by STANDARD_EXPANSION_FACTOR (1e18)
* @dev this logic is very similar to that used in LCFA
*/
function calculateCollateralTokensAmountEquivalentToPrincipalTokens(
uint256 principalAmount
uint256 principalAmount
) public view virtual returns (uint256 collateralTokensAmountToMatchValue) {



// principalPerCollateralAmount
uint256 priceRatioQ96 = IPriceAdapter( priceAdapter )
// Convert Q96 oracle price to 1e18 expansion
uint256 priceRatioQ96 = IPriceAdapter(priceAdapter)
.getPriceRatioQ96(priceRouteHash);




uint256 pricRatio1e18 = MathUpgradeable.mulDiv(
priceRatioQ96,
STANDARD_EXPANSION_FACTOR,
Q96
);

uint256 principalPerCollateralAmount = maxPrincipalPerCollateralAmount == 0
? pricRatio1e18
: MathUpgradeable.min(
pricRatio1e18,
maxPrincipalPerCollateralAmount
);

return
getRequiredCollateral(
principalAmount,
priceRatioQ96 // principalPerCollateralAmount
principalPerCollateralAmount
);
}




/**
* @notice Returns the effective principal-per-collateral price ratio (capped by maxPrincipalPerCollateralAmount if set)
* @dev Mirrors the V2 getPrincipalForCollateralForPoolRoutes ABI for compatibility
* @return The principal per collateral ratio, expanded by STANDARD_EXPANSION_FACTOR (1e18)
*/
function getPrincipalPerCollateralAmount() external view virtual returns (uint256) {
uint256 priceRatioQ96 = IPriceAdapter(priceAdapter)
.getPriceRatioQ96(priceRouteHash);

uint256 priceRatio1e18 = MathUpgradeable.mulDiv(
priceRatioQ96,
STANDARD_EXPANSION_FACTOR,
Q96
);

return maxPrincipalPerCollateralAmount == 0
? priceRatio1e18
: MathUpgradeable.min(
priceRatio1e18,
maxPrincipalPerCollateralAmount
);
}

/**
* @notice Calculates the amount of collateral tokens required for a given principal amount
* @dev Converts principal amount to equivalent collateral based on current price ratio
* @dev Uses the Math.mulDiv function with rounding up to ensure sufficient collateral
* @param _principalAmount The amount of principal tokens to be borrowed
* @param _maxPrincipalPerCollateralAmountQ96 The exchange rate between principal and collateral (expanded by Q96)
* @param _maxPrincipalPerCollateralAmount The exchange rate between principal and collateral (expanded by STANDARD_EXPANSION_FACTOR)
* @return The required amount of collateral tokens, rounded up to ensure sufficient collateralization
*/
function getRequiredCollateral(
uint256 _principalAmount,
uint256 _maxPrincipalPerCollateralAmountQ96 //price ratio Q96
uint256 _maxPrincipalPerCollateralAmount

) internal view virtual returns (uint256) {

return
MathUpgradeable.mulDiv(
_principalAmount,
Q96,
_maxPrincipalPerCollateralAmountQ96,
STANDARD_EXPANSION_FACTOR,
_maxPrincipalPerCollateralAmount,
MathUpgradeable.Rounding.Up
);
);
}


Expand Down Expand Up @@ -1100,7 +1130,17 @@ contract LenderCommitmentGroup_Pool_V3 is



// ------------------------ Pausing functions ------------
/**
* @notice Sets an optional manual cap for principal/collateral price ratio. Only Pool Owner.
* @param _maxPrincipalPerCollateralAmount Price ratio expanded by STANDARD_EXPANSION_FACTOR (1e18). If 0, only oracle price is used.
*/
function setMaxPrincipalPerCollateralAmount(uint256 _maxPrincipalPerCollateralAmount)
external
onlyOwner {
maxPrincipalPerCollateralAmount = _maxPrincipalPerCollateralAmount;
}

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



Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'


const deployFn: DeployFunction = async (hre) => {
hre.log('----------')
hre.log('')
hre.log('Lender Pools V3: Proposing upgrade...')

const lenderCommitmentGroupV3Beacon = await hre.contracts.get('LenderCommitmentGroupBeaconV3')

const tellerV2 = await hre.contracts.get('TellerV2')
const SmartCommitmentForwarder = await hre.contracts.get(
'SmartCommitmentForwarder'
)
const tellerV2Address = await tellerV2.getAddress()
const smartCommitmentForwarderAddress =
await SmartCommitmentForwarder.getAddress()

await hre.upgrades.proposeBatchTimelock({
title: 'Lender Pools V3: Re-enable setMaxPrincipalPerCollateralAmount',
description: `
# Lender Pools V3

* Re-adds setMaxPrincipalPerCollateralAmount so pool owners can set a manual cap on the principal-per-collateral price ratio.
* When set (nonzero), the pool uses the lesser of the oracle price and the manual cap — protecting lenders from inflated oracle values.
* When zero (default), pricing uses the oracle only (no behavior change for existing pools).
`,
_steps: [
{
beacon: lenderCommitmentGroupV3Beacon,
implFactory: await hre.ethers.getContractFactory('LenderCommitmentGroup_Pool_V3'),

opts: {
unsafeAllow: [
'constructor',
'state-variable-immutable',
],
constructorArgs: [
tellerV2Address,
smartCommitmentForwarderAddress,
],
},
},
],
})

hre.log('done.')
hre.log('')
hre.log('----------')

return true
}

// tags and deployment
deployFn.id = 'lender-commitment-group-beacon-v3:upgrade-max-principal'
deployFn.tags = [
'proposal',
'upgrade',
'lender-commitment-group-beacon-v3',
'lender-commitment-group-beacon-v3:upgrade-max-principal',
]
deployFn.dependencies = [
'teller-v2:deploy',
'smart-commitment-forwarder:deploy',
'lender-commitment-group-beacon-v3:deploy',
]
deployFn.skip = async (hre) => {
return hre.network.name !== 'apechain'
}
export default deployFn
3 changes: 2 additions & 1 deletion packages/contracts/deployments/apechain/.migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
"apechain:transfer-timelock-ownership": 1771556073,
"lender-commitment-group-beacon-v3:deploy": 1772162877,
"lender-commitment-group-factory-v3:deploy": 1772162931,
"lender-commitment-forwarder:extensions:flash-swap-rollover:g4-upgrade-apechain": 1775158842
"lender-commitment-forwarder:extensions:flash-swap-rollover:g4-upgrade-apechain": 1775158842,
"lender-commitment-group-beacon-v3:upgrade-max-principal": 1777644534
}
Original file line number Diff line number Diff line change
Expand Up @@ -483,28 +483,28 @@
},
{
"type": "function",
"name": "TELLER_V2",
"name": "STANDARD_EXPANSION_FACTOR",
"constant": true,
"stateMutability": "view",
"payable": false,
"inputs": [],
"outputs": [
{
"type": "address",
"type": "uint256",
"name": ""
}
]
},
{
"type": "function",
"name": "UNISWAP_EXPANSION_FACTOR",
"name": "TELLER_V2",
"constant": true,
"stateMutability": "view",
"payable": false,
"inputs": [],
"outputs": [
{
"type": "uint256",
"type": "address",
"name": ""
}
]
Expand Down Expand Up @@ -1015,6 +1015,20 @@
}
]
},
{
"type": "function",
"name": "getPrincipalPerCollateralAmount",
"constant": true,
"stateMutability": "view",
"payable": false,
"inputs": [],
"outputs": [
{
"type": "uint256",
"name": ""
}
]
},
{
"type": "function",
"name": "getPrincipalTokenAddress",
Expand Down Expand Up @@ -1595,6 +1609,19 @@
],
"outputs": []
},
{
"type": "function",
"name": "setMaxPrincipalPerCollateralAmount",
"constant": false,
"payable": false,
"inputs": [
{
"type": "uint256",
"name": "_maxPrincipalPerCollateralAmount"
}
],
"outputs": []
},
{
"type": "function",
"name": "setWithdrawDelayTime",
Expand Down Expand Up @@ -1888,6 +1915,6 @@
}
],
"receipt": {},
"numDeployments": 1,
"numDeployments": 2,
"implementation": "0x688d3d7D900f38ce095914608AD069d5AA2331DB"
}
3 changes: 1 addition & 2 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teller-protocol/v2-contracts",
"version": "3.1.51",
"version": "3.1.61",
"license": "MIT",
"scripts": {
"forge": "forge",
Expand Down Expand Up @@ -32,7 +32,6 @@
"format:sol": "prettier --config .prettierrc.yml --resolve-plugins-relative-to . --write --loglevel error '{contracts,tests}/**/*.sol'",
"git:future": "./scripts/git/future.sh",
"git:portal": "./scripts/git/portal.sh",
"publish": "yarn npm publish",
"clean": "yarn hh clean && ./scripts/clean.sh",
"prepacklegacy": "./scripts/prepack.sh",
"prepack": "node ./scripts/prepack.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LenderCommitmentGroup_Pool_V3 } from "../../contracts/LenderCommitmentF

contract LenderCommitmentGroup_Pool_V3_Override is LenderCommitmentGroup_Pool_V3 {
uint256 mockRequiredCollateralAmount;
bool useRealGetRequiredCollateral;
uint256 mockSharesExchangeRate;
int256 mockMinimumAmountDifferenceToCloseDefaultedLoan;

Expand Down Expand Up @@ -101,6 +102,10 @@ contract LenderCommitmentGroup_Pool_V3_Override is LenderCommitmentGroup_Pool_V3
mockRequiredCollateralAmount = amt;
}

function set_useRealGetRequiredCollateral(bool _use) public {
useRealGetRequiredCollateral = _use;
}

function force_mint_shares(address guy, uint256 wad) public {
return super.mintShares(guy, wad);
}
Expand Down Expand Up @@ -134,8 +139,11 @@ contract LenderCommitmentGroup_Pool_V3_Override is LenderCommitmentGroup_Pool_V3

function getRequiredCollateral(
uint256 _principalAmount,
uint256 maxPrincipalPerCollateralAmount
uint256 _maxPrincipalPerCollateralAmountQ96
) internal view override returns (uint256) {
if (useRealGetRequiredCollateral) {
return super.getRequiredCollateral(_principalAmount, _maxPrincipalPerCollateralAmountQ96);
}
return mockRequiredCollateralAmount;
}

Expand Down
Loading
Loading