tokamak-network / tokamak-thanos

MIT License
7 stars 3 forks source link

Add checking msg.sender in L2CrossDomainMessage.sendMessage when msg.value is greater than 0 #236

Closed Zena-park closed 2 weeks ago

Zena-park commented 2 weeks ago

When sending a native token in sendMessage of L2CrossDomainMessage, If the sender is not L2 Standard Bridge, all sent a native token will be locked in the L1CrossDomainMessage contract.

There is no way to move TON(native token) from L1's L1CrossDomainMessage when the sender is not L2 Standard Bridge, We need to add 'require' statement if msg.value is greater than 0 in the L2CrossDomainMessage.sendMessage function.

https://github.com/tokamak-network/tokamak-thanos/blob/5ad9baac98217a0c1533969b00076d9a4443edba/packages/tokamak/contracts-bedrock/src/L2/L2CrossDomainMessenger.sol#L41-L45

function _sendMessage(address _to, uint64 _gasLimit, uint256 _value, bytes memory _data) internal override {

        if (msg.value != 0) require(msg.sender == Predeploys.L2_STANDARD_BRIDGE, "Native token must be withdrawn through the bridge.");

        L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: _value }(
            _to, _gasLimit, _data
        );
    }
nguyenzung commented 2 weeks ago

I think there is no issue here

  1. If the target address is not L1StandardBridge, L1CrossDomainMessenger still approves the target address with the requested withdrawal amount, then the target call transferFrom() to withdraw token. The logic is the same as when we use L1StandardBridge and L2StandardBridge
  2. CrossDomainMessenger provides lower API level, so CrossDomainMessenger does not need to know L2_STANDARD_BRIDGE.
Zena-park commented 2 weeks ago

@nguyenzung Thank you for your reply.

Can you provide me some test codes to send and receive a native token using l2CrossDomainMessenger.sendMessage and ton.transferFrom?

Zena-park commented 2 weeks ago

@nguyenzung Thank you for your help.

const sendTx = await (
        await l2CrossDomainMessengerContract
        .connect(l2Wallet)
        .sendMessage(l1Wallet.address, '0x', 200000, { value: amount })
    ).wait()

After executing, finalizing,

ton.transferFrom( l1CrossDomainMessenger, l1Wallet.address,amount)

The TON was successfully transferred from L2 to L1.