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
Oracle
records the price ofCurtaUSD
as1e18
,CurtaWETH
as3_000e18
, andCurtaRebasingWETH
as3_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 ether
of liquidity, and players are supplied with10_000 ether
ofCurtaUSD
and10_000 ether
ofCurtaWETH
.
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.