sherlock-audit / 2022-10-illuminate-judging

3 stars 0 forks source link

HonorLt - Lend or mint after maturity #208

Open sherlock-admin opened 2 years ago

sherlock-admin commented 2 years ago

HonorLt

high

Lend or mint after maturity

Summary

The protocol does not forbid lending or minting after the maturity leaving the possibility to profit from early users.

Vulnerability Detail

Let's take the mint function as an example:

    function mint(
        uint8 p,
        address u,
        uint256 m,
        uint256 a
    ) external unpaused(u, m, p) returns (bool) {
        // Fetch the desired principal token
        address principal = IMarketPlace(marketPlace).token(u, m, p);

        // Transfer the users principal tokens to the lender contract
        Safe.transferFrom(IERC20(principal), msg.sender, address(this), a);

        // Mint the tokens received from the user
        IERC5095(principalToken(u, m)).authMint(msg.sender, a);

        emit Mint(p, u, m, a);

        return true;
    }

It is a simple function that accepts the principal token and mints the corresponding ERC5095 tokens in return. There are no restrictions on timing, the user can mint even after the maturity. Malicious actors can take this as an advantage to pump their bags on behalf of legitimate early users.

Scenario: 1) Legitimate users lend and mint their ERC5095 tokens before maturity. 2) When the maturity kicks in, lender tokens are redeemed and holdings are updated. 3) Legitimate users try to redeem their ERC5095 for the underlying tokens. The formula is (amount * holdings[u][m]) / token.totalSupply(); 4) A malicious actor sandwiches legitimate users, and mints the ERC5095 thus increasing the totalSupply and reducing other user shares. Then redeem principals again and burn their own shares for increased rewards.

Example with concrete values: 1) userA deposits 100 tokens, user B deposits 200 tokens. The total supply minted is 300 ERC5095 tokens. 2) After the maturity the redemption happens and now let's say holdings[u][m] is 330 (+30). 3) userA tries to redeem the underlying. The expected amount is: 100 * 330 / 300 = 110. However, this action is frontrunned by userC (malicious) who mints yet another 500 tokens post-maturity. The total supply becomes 800. The real value userA now receives is: 110 * 330 / 800 = 45.375. 4) After that the malicious actor userC invokes the redemption again, and the holdings[u][m] is now 330 - 45.375 + 550 = 834.625. 5) userC redeems the underlying: 500 * 834.625 / 700 ~= 596.16 (expected was 550). 6) Now all the remaining users will also slightly benefit, e.g. in this case userB redeems what's left: 200 * 238.46 / 200 = 238.46 (expected was 220).

Impact

The amount legitimate users receive will be devaluated, while malicious actor can increase their ROI without meaningfully contributing to the protocol and locking their tokens.

Code Snippet

https://github.com/sherlock-audit/2022-10-illuminate/blob/main/src/Lender.sol#L264-L288

Tool used

Manual Review

Recommendation

Lend/mint should be forbidden post-maturity.

sourabhmarathe commented 1 year ago

https://github.com/Swivel-Finance/illumigrate/pull/236