Skip to content

Commit

Permalink
🚑 debt-manager: validate markets
Browse files Browse the repository at this point in the history
  • Loading branch information
cruzdanilo committed Aug 21, 2023
1 parent 46e8402 commit e73bfb2
Show file tree
Hide file tree
Showing 11 changed files with 458 additions and 295 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-insects-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/protocol": patch
---

🚑 debt-manager: validate markets
291 changes: 148 additions & 143 deletions .gas-snapshot

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions .openzeppelin/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -15279,6 +15279,65 @@
}
}
}
},
"0x7f8421fE6C09B02EAF6905a27863BE66268c6601": {
"address": "0x7f8421fE6C09B02EAF6905a27863BE66268c6601",
"layout": {
"solcVersion": "0.8.17",
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68"
},
{
"label": "callHash",
"offset": 0,
"slot": "1",
"type": "t_bytes32",
"contract": "DebtManager",
"src": "contracts/periphery/DebtManager.sol:669"
},
{
"label": "_msgSender",
"offset": 0,
"slot": "2",
"type": "t_address",
"contract": "DebtManager",
"src": "contracts/periphery/DebtManager.sol:762"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
}
}
}
59 changes: 59 additions & 0 deletions .openzeppelin/optimism.json
Original file line number Diff line number Diff line change
Expand Up @@ -9173,6 +9173,65 @@
}
}
}
},
"0x910E91D24a948c3E36b71B505Fb45fE80E95adB3": {
"address": "0x910E91D24a948c3E36b71B505Fb45fE80E95adB3",
"layout": {
"solcVersion": "0.8.17",
"storage": [
{
"label": "_initialized",
"offset": 0,
"slot": "0",
"type": "t_uint8",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:63",
"retypedFrom": "bool"
},
{
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "t_bool",
"contract": "Initializable",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:68"
},
{
"label": "callHash",
"offset": 0,
"slot": "1",
"type": "t_bytes32",
"contract": "DebtManager",
"src": "contracts/periphery/DebtManager.sol:669"
},
{
"label": "_msgSender",
"offset": 0,
"slot": "2",
"type": "t_address",
"contract": "DebtManager",
"src": "contracts/periphery/DebtManager.sol:762"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"label": "bytes32",
"numberOfBytes": "32"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
}
}
}
}
}
59 changes: 40 additions & 19 deletions contracts/periphery/DebtManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ contract DebtManager is Initializable {
/// @param deposit The amount of assets to deposit.
/// @param ratio The number of times that the current principal will be leveraged, represented with 18 decimals.
function noTransferLeverage(Market market, uint256 deposit, uint256 ratio) internal {
checkMarket(market);
uint256[] memory amounts = new uint256[](1);
ERC20[] memory tokens = new ERC20[](1);
tokens[0] = market.asset();
Expand Down Expand Up @@ -182,6 +183,7 @@ contract DebtManager is Initializable {
/// @param withdraw The amount of assets that will be withdrawn to `_msgSender`.
/// @param ratio The number of times that the current principal will be leveraged, represented with 18 decimals.
function deleverage(Market market, uint256 withdraw, uint256 ratio) public msgSender {
checkMarket(market);
RollVars memory r;
r.amounts = new uint256[](1);
r.tokens = new ERC20[](1);
Expand Down Expand Up @@ -300,14 +302,17 @@ contract DebtManager is Initializable {
uint256 ratio,
uint160 sqrtPriceLimitX96
) internal {
checkMarket(marketIn);
checkMarket(marketOut);
LeverageVars memory v;
v.assetIn = address(marketIn.asset());
v.assetOut = address(marketOut.asset());
v.sender = _msgSender;

v.marketIn = marketIn;
v.marketOut = marketOut;
v.amount =
crossPrincipal(marketIn, marketOut, deposit, v.sender).mulWadDown(ratio) -
marketIn.maxWithdraw(v.sender) -
crossPrincipal(v.marketIn, v.marketOut, deposit, v.sender).mulWadDown(ratio) -
v.marketIn.maxWithdraw(v.sender) -
deposit;
if (v.amount > 0) {
PoolKey memory poolKey = PoolAddress.getPoolKey(v.assetIn, v.assetOut, fee);
Expand All @@ -318,8 +323,8 @@ contract DebtManager is Initializable {
sqrtPriceLimitX96,
abi.encode(
SwapCallbackData({
marketIn: marketIn,
marketOut: marketOut,
marketIn: v.marketIn,
marketOut: v.marketOut,
assetIn: v.assetIn,
assetOut: v.assetOut,
principal: deposit,
Expand All @@ -330,7 +335,7 @@ contract DebtManager is Initializable {
)
);
} else {
marketIn.deposit(deposit, v.sender);
v.marketIn.deposit(deposit, v.sender);
}
}

Expand All @@ -349,33 +354,36 @@ contract DebtManager is Initializable {
uint256 ratio,
uint160 sqrtPriceLimitX96
) public msgSender {
checkMarket(marketIn);
checkMarket(marketOut);
LeverageVars memory v;
v.assetIn = address(marketIn.asset());
v.assetOut = address(marketOut.asset());
v.sender = _msgSender;

v.marketIn = marketIn;
v.marketOut = marketOut;
v.amount =
floatingBorrowAssets(marketOut) -
floatingBorrowAssets(v.marketOut) -
(
ratio > 1e18
? previewAssetsOut(
marketIn,
marketOut,
(crossPrincipal(marketIn, marketOut, 0, v.sender) - withdraw).mulWadDown(ratio - 1e18)
v.marketIn,
v.marketOut,
(crossPrincipal(v.marketIn, v.marketOut, 0, v.sender) - withdraw).mulWadDown(ratio - 1e18)
)
: 0
);

PoolKey memory poolKey = PoolAddress.getPoolKey(v.assetIn, v.assetOut, fee);
IUniswapV3Pool(PoolAddress.computeAddress(uniswapV3Factory, poolKey)).swap(
v.poolKey = PoolAddress.getPoolKey(v.assetIn, v.assetOut, fee);
IUniswapV3Pool(PoolAddress.computeAddress(uniswapV3Factory, v.poolKey)).swap(
address(this),
v.assetIn == poolKey.token0,
v.assetIn == v.poolKey.token0,
-int256(v.amount),
sqrtPriceLimitX96,
abi.encode(
SwapCallbackData({
marketIn: marketIn,
marketOut: marketOut,
marketIn: v.marketIn,
marketOut: v.marketOut,
assetIn: v.assetIn,
assetOut: v.assetOut,
principal: withdraw,
Expand Down Expand Up @@ -425,6 +433,7 @@ contract DebtManager is Initializable {
uint256 maxBorrowAssets,
uint256 percentage
) public msgSender {
checkMarket(market);
RollVars memory r;
r.amounts = new uint256[](1);
r.tokens = new ERC20[](1);
Expand Down Expand Up @@ -509,6 +518,7 @@ contract DebtManager is Initializable {
uint256 maxRepayAssets,
uint256 percentage
) public msgSender {
checkMarket(market);
RollVars memory r;
r.amounts = new uint256[](1);
r.tokens = new ERC20[](1);
Expand Down Expand Up @@ -568,6 +578,7 @@ contract DebtManager is Initializable {
uint256 maxBorrowAssets,
uint256 percentage
) public msgSender {
checkMarket(market);
RollVars memory r;
r.amounts = new uint256[](1);
r.tokens = new ERC20[](1);
Expand Down Expand Up @@ -711,6 +722,7 @@ contract DebtManager is Initializable {
callHash = bytes32(0);

(Market market, bytes[] memory calls) = abi.decode(userData, (Market, bytes[]));
checkMarket(market);
for (uint256 i = 0; i < calls.length; ) {
address(market).functionCall(calls[i], "");
unchecked {
Expand All @@ -728,6 +740,9 @@ contract DebtManager is Initializable {
/// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
SwapCallbackData memory s = abi.decode(data, (SwapCallbackData));
checkMarket(s.marketIn);
checkMarket(s.marketOut);

PoolKey memory poolKey = PoolAddress.getPoolKey(s.assetIn, s.assetOut, s.fee);
assert(msg.sender == PoolAddress.computeAddress(uniswapV3Factory, poolKey));

Expand All @@ -752,6 +767,11 @@ contract DebtManager is Initializable {
delete _msgSender;
}

function checkMarket(Market market) internal view {
(, , , bool listed, ) = auditor.markets(market);
if (!listed) revert MarketNotListed();
}

/// @notice Calls `token.permit` on behalf of `permit.account`.
/// @param token The `ERC20` to call `permit`.
/// @param assets The amount of assets to allow.
Expand Down Expand Up @@ -800,9 +820,7 @@ contract DebtManager is Initializable {
/// @dev The Market must be listed by the Auditor in order to be valid for approval.
/// @param market The Market to spend the contract's balance.
function approve(Market market) public {
(, , , bool isListed, ) = auditor.markets(market);
if (!isListed) revert MarketNotListed();

checkMarket(market);
market.asset().safeApprove(address(market), type(uint256).max);
}

Expand Down Expand Up @@ -860,6 +878,9 @@ struct LeverageVars {
address assetIn;
address assetOut;
uint256 amount;
PoolKey poolKey;
Market marketIn;
Market marketOut;
}

interface IBalancerVault {
Expand Down
8 changes: 2 additions & 6 deletions deployments/ethereum/DebtManager.json

Large diffs are not rendered by default.

50 changes: 25 additions & 25 deletions deployments/ethereum/DebtManager_Implementation.json

Large diffs are not rendered by default.

0 comments on commit e73bfb2

Please sign in to comment.