# Security research disclosure | Optimism Bridge Portal

By [Shanmuga Bharathi](https://paragraph.com/@shanmuga-bharathi) · 2024-04-10

---

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:

1.  Base org
    
2.  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:_**

1.  Assume that a Staking Protocol deploys a Staking contract on L1 and Optimism(L2).
    
2.  The L1 Stake contract receives user ETH deposits and locks funds on Optimism(L2).
    
3.  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.
    
4.  Now User deposits on the Staking protocol with `msg.value of 0.01 ether`, mistakenly or intentionally the user fills the `_value` param as `0.1 ether as 100000000000000000 wei`
    
5.  Assume the L1 Staking contract Alias on L2 has a balance of 0.1 eth.
    
6.  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.
    
7.  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.
    
8.  Gaining malicious user's locked balance as 0.1 ether.
    

![Attack Flow](https://storage.googleapis.com/papyrus_images/9f4fe41e7e5e551c0c681e12b0b669a0ad30624cfff6448356d965e6e12a405d.png)

Attack Flow

**_Proof of concept:_**

Add these three files foundry test suite `src/` directory

[https://gist.github.com/shanb1605/2169175a19230158a70bcfedc1056811](https://gist.github.com/shanb1605/2169175a19230158a70bcfedc1056811)

Add this test file to `test/`

[https://gist.github.com/shanb1605/0ab0736a89302c13fc6e7479707de709](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** t**he Optimism Portal needs to validate the** `msg.value` **and its parameters.**

---

*Originally published on [Shanmuga Bharathi](https://paragraph.com/@shanmuga-bharathi/security-research-disclosure-optimism-bridge-portal)*
