Intro:
The OptimismPortal
contract is an L1 smart contract that can be used by both smart contracts and EOAs to create L2 transactions without the direct involvement of the Sequencer. Many users already interact with this contract indirectly when they bridge ETH or other tokens between L1 and L2 via the Standard Bridge system available on all OP Stack chains.
This write-up showcases that multiple forks of the Optimism Portal contract are affected. Some affected forked projects are:
-
Base org
-
Blast L2
Also, this article insists any third party using the Optimism portal needs to be aware of this bug.
Description:
The Optimism Portal allows users to Bridge ETH via depositTransaction()
to L2. The Bug Relies on the depositTransaction()
function where msg.value is not checked properly. Uses both msg.value and _value
Transaction opaque data causes funds lost on the L2 side in some Scenarios. The Sequencer takes _value
as first priority not msg.value
sent to Portal.
Attack Scenario:
-
Assume that a Staking Protocol deploys a Staking contract on L1 and Optimism(L2).
-
The L1 Stake contract receives user ETH deposits and locks funds on Optimism(L2).
-
Assume that the protocol also misses the check
msg.value == _value
Believing Op Portal will take care of those checks and believes only msg.value will lock for User on L2. -
Now User deposits on the Staking protocol with
msg.value of 0.01 ether
, mistakenly or intentionally the user fills the_value
param as0.1 ether as 100000000000000000 wei
-
Assume the L1 Staking contract Alias on L2 has a balance of 0.1 eth.
-
Transaction Deposited. As the Sequencer only follows the
_value
not msg.value. The Sequencer inits the Transaction from L1 contract Alias with callvalue() of 0.1 ether. -
The L1 contract Alias address lost 0.1 eth to the L2 Staking contract by locking funds in favour of the user who deposited 0.01 ether on L1.
-
Gaining malicious user's locked balance as 0.1 ether.
Proof of concept:
Add these three files foundry test suite src/
directory
https://gist.github.com/shanb1605/2169175a19230158a70bcfedc1056811
Add this test file to test/
https://gist.github.com/shanb1605/0ab0736a89302c13fc6e7479707de709
Run forge test --mp test/OptimsimPoc.t.sol -vvvv
Impact:
The L1 Contract Alias address on L2 will lose the ether or Temporarily/Permanently funds get Frozen.
Recommendation(s):
The OptimismPortal.sol
the contract should be checked given _value
parameter is equal to msg.value.
require(_value == msg.value, "_value not Enough");
(OR)
opaqueData = abi.encodePacked(msg.value, msg.value, _gasLimit, _isCreation, _data);
Response:
Optimism and its fork do not take responsibility and solely shift towards to the affected project’s duty to ensure and make a check on msg.value.
So any project relying on the Optimism Portal needs to validate the msg.value
and its parameters.
评论 (0)