When a user wants to claim the MOR
token reward on L2 Arbitrum
, the user interacts with the claim
function on Distribution.sol
. Then, after all the claim requirements have been fulfilled by the user, Distribution
call the L1Sender.sol
which sends a message via the LayerZero
endpoint with the send function and if successful it will be received by the L2MessageReceiver.sol
and will mint the MOR
token to the user's address on L2 Arbitrum
as a reward.
The problem here is {value : msg.value}
on send
function is not set in the codebase so that if the user sends a fee that is less than what is required for execution on the destination chain then the transaction will revert.
Scenario :
Alice has deposited tokens into a pool on Distribution.sol
. Over time, Alice has accrued reward tokens through the pool's staking mechanism. Alice then decides to claim her accumulated rewards.
Steps:
Alice calls the claim
function:
Alice specifies the pool ID and her own address.
Alice also need to specify the amount of ether she wants to send for gas or include as part of the reward.
Function execution:
The function checks if the claim period has elapsed (e.g., 24 hours since the last claim) and if Alice has any pending rewards.
If eligible, the function calculates Alice's current pending rewards based on the pool's reward rate and her deposited tokens.
The function updates pool and user data, resetting Alice's pending rewards and recording the current timestamp and rate.
Finally, the function calls the L1Sender.sendMintMessage
with the following parameters:
user_
: Alice's address (to mint the reward tokens)
pendingRewards_
: The calculated amount of rewards
_msgSender()
: The address of the contract calling the function
Transaction revert:
Back to claim step point number 2, Alice did not provide enough native gas fee for executing transaction on destination chain. This can cause transaction revert.
Based on LayerZero
docs, {value : msg.value}
on send
function must be set or it will be revert because user not provide enough gas.
You will note in the topmost example we call
send()
with{value: msg.value}
this is becausesend()
requires a bit of native gas token so the relayer can complete the message delivery on the destination chain. If you don't set this value you might get this error when callingendpoint.send()
In this coded POC
, assume the user has passed all the requirements to claim the MOR
token reward. But the user does not pay enough native gas to execute the transaction on the destination chain which causes the transaction to revert.
Result :
This coded POC
was written using the default environment of the protocol so just input the Distribution.test.ts
file and paste it in the claim section then the POC
can be executed immediately.
claim
function will revert and can't be used, user loss the gasfee
and not receive the reward token yet.
Manual Review
Consider using the estimateFees()
function to estimate fees so that the send()
execution not revert because not enough native gas fee.
The implementation :
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.