hats-finance / Most--Aleph-Zero-Bridge-0xab7c1d45ae21e7133574746b2985c58e0ae2e61d

Aleph Zero bridge to Ethereum
Apache License 2.0
0 stars 1 forks source link

`pocket_money` spam send attack #22

Open hats-bug-reporter[bot] opened 6 months ago

hats-bug-reporter[bot] commented 6 months ago

Github username: @0xfuje Twitter username: 0xfuje Submission hash (on-chain): 0x663c06e82afe59963787cfcdd905651ec3297d1d187074b98546cd0ebc0fae25 Severity: medium

Description:

Impact

Devaluation of AZERO -> loss of significant value for holders

Description

During a cross-chain transfer from ETH to AZERO user will receive some additional pocket_money to have some gas to submit transactions on AlephZero blockchain. In the future when ETH gas fees are really cheap, AZERO price could skyrocket quickly during a mass market movement, then it's possible that the pocket_money received is worth more than the gas fees paid on ETH. Since there is no restriction besides a zero amount check on the bridge on ETH and ERC20 transfer amounts this can be exploited by massive spam sending of transactions with 1 wei amount of ERC20 or ETH funds on ETH (which are basically worthless). The attacker would continually sell the accumulated AZERO to profit from the exploit which could quickly devalue the token.

The damage and speed of the exploit depends on:

If the above variables are favorable for the attacker -> he can sell until the AZERO token lost so much value that the exploit is no longer profitable.

Most.sol - sendRequest()

    function sendRequest(
        bytes32 srcTokenAddress,
        uint256 amount,
        bytes32 destReceiverAddress
    ) external whenNotPaused {
        if (amount == 0) revert ZeroAmount(); 

        IERC20 token = IERC20(bytes32ToAddress(srcTokenAddress));

        bytes32 destTokenAddress = supportedPairs[srcTokenAddress];
        if (destTokenAddress == 0x0) revert UnsupportedPair();

        // lock tokens in this contract
        // message sender needs to give approval else this tx will revert

        token.safeTransferFrom(msg.sender, address(this), amount);

        emit CrosschainTransferRequest( 
            committeeId,
            destTokenAddress,
            amount,
            destReceiverAddress,
            requestNonce
        );

        ++requestNonce;
    }

Note on severity: Low likehood + High impact => Medium severity

Recommendation

Consider to defend against this potential exploit by subtracting a small fee in send functions that is roughly equivalent (or more) on ETH that pocket_money is on AZERO. For example: for less complexity we can use only ETH as a pocket_money fee, with a setter function restricted by authorized actor: setPocketFee(), both sendRequest() and sendRequestNative() would be payable and would take pocketFee amount of msg.value. Potentially users could also have the decision to get pocket_money or not (by paying the fee).

krzysztofziobro commented 6 months ago

Invalid submission: A PoC is required for submission to be considered valid. You can create a new submission that contains a working PoC.