Skip to content

Commit

Permalink
fix scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
kovalgek committed Apr 15, 2024
1 parent f54eecd commit bc1c56f
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 29 deletions.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ REBASABLE_TOKEN=
L1_OP_STACK_TOKEN_RATE_PUSHER=

# Gas limit required to complete pushing token rate on L2.
# Default is: 300_000.
# This value was calculated by formula:
# l2GasLimit = (gas cost of L2Bridge.finalizeDeposit() + OptimismPortal.minimumGasLimit(depositData.length)) * 1.5
L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE=

# A time period when token rate can be considered outdated.
RATE_OUTDATED_DELAY=86400 # default is 24 hours
TOKEN_RATE_OUTDATED_DELAY=86400 # default is 86400 (24 hours)

# Address of L1 token bridge proxy.
L1_TOKEN_BRIDGE=
Expand Down
8 changes: 4 additions & 4 deletions .storage-layout
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@
|------|------|------|--------|-------|----------|

=======================
L1ERC20TokenBridge
L1ERC20ExtendedTokensBridge
=======================

| Name | Type | Slot | Offset | Bytes | Contract |
|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------|
| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L1ERC20TokenBridge.sol:L1ERC20TokenBridge |
| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L1ERC20ExtendedTokensBridge.sol:L1ERC20ExtendedTokensBridge |

=======================
➡ L1ERC20TokenGateway
Expand All @@ -81,12 +81,12 @@
|------|------|------|--------|-------|----------|

=======================
L2ERC20TokenBridge
L2ERC20ExtendedTokensBridge
=======================

| Name | Type | Slot | Offset | Bytes | Contract |
|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------|
| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L2ERC20TokenBridge.sol:L2ERC20TokenBridge |
| _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L2ERC20ExtendedTokensBridge.sol:L2ERC20ExtendedTokensBridge |

=======================
➡ L2ERC20TokenGateway
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ The configuration of the deployment scripts happens via the ENV variables. The f
- [`TOKEN`](#TOKEN) - address of the non-rebasable token to deploy a new bridge on the Ethereum chain.
- [`REBASABLE_TOKEN`] (#REBASABLE_TOKEN) - address of the rebasable token to deploy new bridge on the Ethereum chain.
- [`L1_OP_STACK_TOKEN_RATE_PUSHER`](#L1_OP_STACK_TOKEN_RATE_PUSHER) - address of token rate pusher. Required to config TokenRateOracle.
- [`L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE`](#L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE) - gas limit required to complete pushing token rate on L2.
- [`RATE_OUTDATED_DELAY`](#RATE_OUTDATED_DELAY) - a time period when token rate can be considered outdated. Default is 24 hours.
- [`L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE`](#L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE) - gas limit required to complete pushing token rate on L2.This value was calculated by formula: l2GasLimit = (gas cost of L2Bridge.finalizeDeposit() + OptimismPortal.minimumGasLimit(depositData.length)) * 1.5
- [`TOKEN_RATE_OUTDATED_DELAY`](#TOKEN_RATE_OUTDATED_DELAY) - a time period when token rate can be considered outdated. Default is 86400 (24 hours).
- [`L1_TOKEN_BRIDGE`](#L1_TOKEN_BRIDGE) - address of L1 token bridge.
- [`L2_TOKEN_BRIDGE`](#L2_TOKEN_BRIDGE) - address of L2 token bridge.
- [`L2_TOKEN`](#L2_TOKEN) - address of the non-rebasable token on L2.
Expand Down
8 changes: 4 additions & 4 deletions artifacts-opt.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
{
"artifactPath": "artifacts/contracts/proxy/OssifiableProxy.sol/OssifiableProxy.json",
"sourcePath": "contracts/proxy/OssifiableProxy.sol",
"name": "L2ERC20TokenBridge proxy",
"name": "L2ERC20ExtendedTokensBridge proxy",
"address": "0x8E01013243a96601a86eb3153F0d9Fa4fbFb6957"
},
{
"artifactPath": "artifacts/contracts/optimism/L2ERC20TokenBridge.sol/L2ERC20TokenBridge.json",
"sourcePath": "contracts/optimism/L2ERC20TokenBridge.sol",
"name": "L2ERC20TokenBridge",
"artifactPath": "artifacts/contracts/optimism/L2ERC20ExtendedTokensBridge.sol/L2ERC20ExtendedTokensBridge.json",
"sourcePath": "contracts/optimism/L2ERC20ExtendedTokensBridge.sol",
"name": "L2ERC20ExtendedTokensBridge",
"address": "0x23B96aDD54c479C6784Dd504670B5376B808f4C7",
"txHash": "0x5d69e9c6ec1d634f0d90812c2189c925993d1fffbc9b0b416fdc123e15407c56"
},
Expand Down
2 changes: 1 addition & 1 deletion contracts/arbitrum/L2ERC20TokenGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pragma solidity 0.8.10;

import {IERC20Bridged} from "../token/interfaces/IERC20Bridged.sol";
import {IERC20Bridged} from "../token/ERC20Bridged.sol";
import {IL2TokenGateway, IInterchainTokenGateway} from "./interfaces/IL2TokenGateway.sol";

import {L2CrossDomainEnabled} from "./L2CrossDomainEnabled.sol";
Expand Down
28 changes: 28 additions & 0 deletions contracts/arbitrum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,34 @@ Returns a `bool` value indicating whether the operation succeeded.
Transfers `amount` of token from the `from_` account to `to_` using the allowance mechanism. `amount_` is then deducted from the caller's allowance. Returns a `bool` value indicating whether the operation succeed.

#### `increaseAllowance(address,uint256)`

> **Visibility:**     `external`
>
> **Returns**        `(bool)`
>
> **Arguments:**
>
> - **`spender_`** - an address of the tokens spender
> - **`addedValue_`** - a number to increase allowance
>
> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)`
Atomically increases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed.

#### `decreaseAllowance(address,uint256)`

> **Visibility:**     `external`
>
> **Returns**        `(bool)`
>
> **Arguments:**
>
> - **`spender_`** - an address of the tokens spender
> - **`subtractedValue_`** - a number to decrease allowance
>
> **Emits:** `Approval(address indexed owner, address indexed spender, uint256 value)`
Atomically decreases the allowance granted to `spender` by the caller. Returns a `bool` value indicating whether the operation succeed.

## `ERC20Bridged`

**Implements:** [`IERC20Bridged`](https://github.com/lidofinance/lido-l2/blob/main/contracts/token/interfaces/IERC20Bridged.sol)
Expand Down
2 changes: 1 addition & 1 deletion scripts/optimism/deploy-new-impls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async function main() {
tokenBridgeProxyAddress: deploymentConfig.l2TokenBridge,
tokenProxyAddress: deploymentConfig.l2Token,
tokenRateOracleProxyAddress: deploymentConfig.l2TokenRateOracle,
tokenRateOracleRateOutdatedDelay: deploymentConfig.rateOutdatedDelay,
tokenRateOracleRateOutdatedDelay: deploymentConfig.tokenRateOutdatedDelay,
}
);

Expand Down
2 changes: 1 addition & 1 deletion scripts/optimism/deploy-oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async function main() {
.oracleDeployScript(
deploymentConfig.l1Token,
deploymentConfig.l2GasLimitForPushingTokenRate,
deploymentConfig.rateOutdatedDelay,
deploymentConfig.tokenRateOutdatedDelay,
{
deployer: ethDeployer,
admins: {
Expand Down
31 changes: 31 additions & 0 deletions test/optimism/L2ERC20ExtendedTokensBridge.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,37 @@ unit("Optimism:: L2ERC20ExtendedTokensBridge", ctxFactory)
);
})

.test("withdraw() :: not from EOA", async (ctx) => {
const {
l2TokenBridge,
accounts: { emptyContractEOA },
stubs: { l2TokenRebasable, l2TokenNonRebasable },
} = ctx;

await assert.revertsWith(
l2TokenBridge
.connect(emptyContractEOA)
.withdraw(
l2TokenNonRebasable.address,
wei`1 ether`,
wei`1 gwei`,
"0x"
),
"ErrorSenderNotEOA()"
);
await assert.revertsWith(
l2TokenBridge
.connect(emptyContractEOA)
.withdraw(
l2TokenRebasable.address,
wei`1 ether`,
wei`1 gwei`,
"0x"
),
"ErrorSenderNotEOA()"
);
})

.test("withdraw() :: non-rebasable token flow", async (ctx) => {
const {
l2TokenBridge,
Expand Down
65 changes: 57 additions & 8 deletions test/optimism/TokenRateNotifier.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { assert } from "chai";
import { utils } from 'ethers'
import { unit } from "../../utils/testing";
import { wei } from "../../utils/wei";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import {
TokenRateNotifier__factory,
ITokenRatePusher__factory,
Expand All @@ -17,6 +18,15 @@ import {

unit("TokenRateNotifier", ctxFactory)

.test("deploy with zero address owner", async (ctx) => {
const { deployer } = ctx.accounts;

await assert.revertsWith(
new TokenRateNotifier__factory(deployer).deploy(ethers.constants.AddressZero),
"ErrorZeroAddressOwner()"
);
})

.test("initial state", async (ctx) => {
const { tokenRateNotifier } = ctx.contracts;

Expand Down Expand Up @@ -64,10 +74,17 @@ unit("TokenRateNotifier", ctxFactory)

.test("addObserver() :: revert on adding too many observers", async (ctx) => {
const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts;
const { deployer, owner, tokenRateOracle } = ctx.accounts;
const { l2GasLimitForPushingTokenRate } = ctx.constants;

assert.equalBN(await tokenRateNotifier.observersLength(), 0);
const maxObservers = await tokenRateNotifier.MAX_OBSERVERS_COUNT();
for (let i = 0; i < maxObservers.toNumber(); i++) {

const {
opStackTokenRatePusher
} = await getOpStackTokenRatePusher(deployer, owner, tokenRateOracle, l2GasLimitForPushingTokenRate);

await tokenRateNotifier
.connect(ctx.accounts.owner)
.addObserver(opStackTokenRatePusher.address);
Expand All @@ -82,6 +99,21 @@ unit("TokenRateNotifier", ctxFactory)
);
})

.test("addObserver() :: revert on adding the same observer twice", async (ctx) => {
const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts;

await tokenRateNotifier
.connect(ctx.accounts.owner)
.addObserver(opStackTokenRatePusher.address);

await assert.revertsWith(
tokenRateNotifier
.connect(ctx.accounts.owner)
.addObserver(opStackTokenRatePusher.address),
"ErrorAddExistedObserver()"
);
})

.test("addObserver() :: happy path of adding observer", async (ctx) => {
const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts;

Expand Down Expand Up @@ -204,10 +236,18 @@ unit("TokenRateNotifier", ctxFactory)

.run();

async function ctxFactory() {
const [deployer, owner, stranger, tokenRateOracle] = await ethers.getSigners();
async function getOpStackTokenRatePusher(
deployer: SignerWithAddress,
owner: SignerWithAddress,
tokenRateOracle: SignerWithAddress,
l2GasLimitForPushingTokenRate: number) {

const tokenRateNotifier = await new TokenRateNotifier__factory(deployer).deploy(owner.address);

const l1MessengerStub = await new CrossDomainMessengerStub__factory(
deployer
).deploy({ value: wei.toBigNumber(wei`1 ether`) });

const l1TokenRebasableStub = await new ERC20BridgedStub__factory(deployer).deploy(
"L1 Token Rebasable",
"L1R"
Expand All @@ -219,19 +259,28 @@ async function ctxFactory() {
"L1NR"
);

const l1MessengerStub = await new CrossDomainMessengerStub__factory(
deployer
).deploy({ value: wei.toBigNumber(wei`1 ether`) });

const l2GasLimitForPushingTokenRate = 123;

const opStackTokenRatePusher = await new OpStackTokenRatePusher__factory(deployer).deploy(
l1MessengerStub.address,
l1TokenNonRebasableStub.address,
tokenRateOracle.address,
l2GasLimitForPushingTokenRate
);

return {tokenRateNotifier, opStackTokenRatePusher, l1MessengerStub, l1TokenNonRebasableStub}
}

async function ctxFactory() {
const [deployer, owner, stranger, tokenRateOracle] = await ethers.getSigners();

const l2GasLimitForPushingTokenRate = 123;

const {
tokenRateNotifier,
opStackTokenRatePusher,
l1MessengerStub,
l1TokenNonRebasableStub
} = await getOpStackTokenRatePusher(deployer, owner, tokenRateOracle, l2GasLimitForPushingTokenRate);

return {
accounts: { deployer, owner, stranger, tokenRateOracle },
contracts: { tokenRateNotifier, opStackTokenRatePusher, l1MessengerStub, l1TokenNonRebasableStub },
Expand Down
4 changes: 2 additions & 2 deletions test/optimism/TokenRateOracle.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ unit("TokenRateOracle", ctxFactory)
const { bridge, l1TokenBridgeEOA } = ctx.accounts;

assert.equal(await tokenRateOracle.MESSENGER(), l2MessengerStub.address);
assert.equal(await tokenRateOracle.BRIDGE(), bridge.address);
assert.equal(await tokenRateOracle.L2_ERC20_TOKEN_BRIDGE(), bridge.address);
assert.equal(await tokenRateOracle.L1_TOKEN_RATE_PUSHER(), l1TokenBridgeEOA.address);
assert.equalBN(await tokenRateOracle.RATE_OUTDATED_DELAY(), 86400);
assert.equalBN(await tokenRateOracle.TOKEN_RATE_OUTDATED_DELAY(), 86400);

assert.equalBN(await tokenRateOracle.latestAnswer(), 0);

Expand Down
2 changes: 1 addition & 1 deletion test/token/ERC20Rebasable.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ unit("ERC20Rebasable", ctxFactory)

.test("wrappedToken() :: has the same address is in constructor", async (ctx) => {
const { rebasableProxied, wrappedToken } = ctx.contracts;
assert.equal(await rebasableProxied.WRAPPED_TOKEN(), wrappedToken.address)
assert.equal(await rebasableProxied.TOKEN_TO_WRAP_FROM(), wrappedToken.address)
})

.test("tokenRateOracle() :: has the same address is in constructor", async (ctx) => {
Expand Down
4 changes: 2 additions & 2 deletions utils/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface MultiChainDeploymentConfig {
l1RebasableToken: string;
l1OpStackTokenRatePusher: string;
l2GasLimitForPushingTokenRate: number;
rateOutdatedDelay: number;
tokenRateOutdatedDelay: number;
l1TokenBridge: string;
l2TokenBridge: string;
l2Token: string;
Expand All @@ -30,7 +30,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig {
l1RebasableToken: env.address("REBASABLE_TOKEN"),
l1OpStackTokenRatePusher: env.address("L1_OP_STACK_TOKEN_RATE_PUSHER"),
l2GasLimitForPushingTokenRate: Number(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")),
rateOutdatedDelay: Number(env.string("RATE_OUTDATED_DELAY")),
tokenRateOutdatedDelay: Number(env.string("TOKEN_RATE_OUTDATED_DELAY")),
l1TokenBridge: env.address("L1_TOKEN_BRIDGE"),
l2TokenBridge: env.address("L2_TOKEN_BRIDGE"),
l2Token: env.address("L2_TOKEN"),
Expand Down
4 changes: 2 additions & 2 deletions utils/optimism/deploymentOracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function deploymentOracle(
async oracleDeployScript(
l1Token: string,
l2GasLimitForPushingTokenRate: number,
rateOutdatedDelay: number,
tokenRateOutdatedDelay: number,
l1Params: OptDeployScriptParams,
l2Params: OptDeployScriptParams,
): Promise<[OracleL1DeployScript, OracleL2DeployScript]> {
Expand Down Expand Up @@ -109,7 +109,7 @@ export default function deploymentOracle(
optAddresses.L2CrossDomainMessenger,
ethers.constants.AddressZero,
expectedL1OpStackTokenRatePusherImplAddress,
rateOutdatedDelay,
tokenRateOutdatedDelay,
options?.overrides,
],
afterDeploy: (c) =>
Expand Down

0 comments on commit bc1c56f

Please sign in to comment.