Dai++
Description¶
MakerDAO is such a complex codebase, and we all know that larger codebases are more likely to have bugs. I simplified everything, so there shouldn't be any bugs here.
Deploy.s.sol
src/Challenge.sol
src/SystemConfiguration.sol
src/Account.sol
AccountManager.sol
src/Stablecoin.sol
Solution¶
- The challenge is solved if the total supply of
Stablecoinis greater than \(10^{12} \times 10^{18}\) - Accounts authorized by the
SystemConfigurationcontract can mint stable coins. Only the owner ofSystemConfigurationcan update system contracts (i.e. authorized accounts) and theAccountManagercontract is the only authorized contract -
In the
AccountManagercontract, only valid accounts can mint stable coins. Meanwhile, the debt on the account will increase -
In the
increaseDebt()function, if the account is not healthy after the debt is increased, the transaction will fail. However, the player don't have enough ETH to mint \(10^{12}\) stable coins and keep the account healthy -
Notice that
AccountManagerusesClonesWithImmutableArgsto create new accounts. When interacting with theAccount, the immutable arguments will be read from calldata, saving gas costs. However, there's a comment in theClonesWithImmutableArgs -
Since the immutable arguments are stored in the code region of the created proxy contract, the code size will be calculated based on the data length during the deployment. However, the code size that should be returned is also stored in 2 bytes. Therefore, if
runSizeexceeds 65535 bytes, a broken contract may be deployed. We can then treatincreaseDebt()as a phantom function and ignore the call -
The existing arguments length is
20 + 20 + 32 = 72bytes and the length of encodedrecoveryAddresseswill be a multiple of 32 bytes
Exploitation¶
Flag¶
PCTF{0V3RFl0W5_WH3r3_Y0u_L3a57_3xp3C7_17}