Write-up for CurtaLending
Overview
Initially, players are given 10,000 curtaUSD tokens and 10,000 curtaWETH tokens. Using only these provided assets, the goal is to exploit the contract's vulnerabilities to obtain an additional 10,000 curtaUSD and 20,000 curtaWETH tokens. The following code snippet implements these conditions:
Starting position breakdown
You begin the challenge by calling deploy on FailedLendingMarket,
the challenge contract, which deploys an instance of the challenge contract
with the starting conditions.
Now, let's delve into how the problem environment is configured. The following is a summary of what happens when the problem is created for a player:
- 3 lending markets (instances of
CurtaLending) are created:CurtaUSD,CurtaWETH, andCurtaRebasingWETH. - The oracle contract
Oraclerecords the price ofCurtaUSDas1e18,CurtaWETHas3_000e18, andCurtaRebasingWETHas3_100e18. CurtaUSD's interest rate is set to 5% with a borrow loan-to-value (LTV) of 80%, a liquidation LTV of 90%, and a liquidation bonus of 5%.CurtaWETH's interest rate is set to 3% with a borrow LTV of 70%, a liquidation LTV of 80%, and a liquidation bonus of 5%.- Similarly to
CurtaWETH,CurtaRebasingWETH's interest rate is also set to 3% with a borrow LTV of 70%, a liquidation LTV of 80%, and a liquidation bonus of 5%. - Each of the three lending markets are seeded with
10_000 etherof liquidity, and players are supplied with10_000 etherofCurtaUSDand10_000 etherofCurtaWETH.
The following code segment is equivalent to the summary above.
Solution
The functions that players can call in each of the CurtaLending contracts are as follows:
By examining the code of the withdrawCollateral function, you can find a vulnerability that allows you to bypass the health factor check.
The health factor is the ratio of the value of your deposited assets against the borrowed assets and its underlying value. Lending markets use this metric to determine if a position is healthy or not.
The formula used to calculate the value of the collateral by its quantity is _userInfo.collateralAmount - amount. However, when amount is 0, the contract intends to withdraw all the collateral. This means that the health factor is calculated based on the state before the withdrawal of the collateral, allowing an attacker to bypass the code that checks if the position is healthy.
Consequently, it leads to bad debt.
By exploiting this vulnerability, you can solve the challenge.
Solve script
Check out our solve test below for more details.