Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: supply decimals and CCTP domain in custom token adapter #690

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,42 @@
// ArbRetryableTx.getSubmissionPrice). ArbRetryableTicket precompile interface exists at L2 address
// 0x000000000000000000000000000000000000006E.
// The Arbitrum Inbox requires that this uses 18 decimal precision.
uint256 public immutable L2_MAX_SUBMISSION_COST;

Check warning on line 48 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 48 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// L2 Gas price bid for immediate L2 execution attempt (queryable via standard eth*gasPrice RPC)
// The Arbitrum Inbox requires that this is specified in gWei (e.g. 1e9 = 1 gWei)
uint256 public immutable L2_GAS_PRICE;

Check warning on line 52 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 52 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// Native token expected to be sent in L2 message. Should be 0 for all use cases of this constant, which
// includes sending messages from L1 to L2 and sending Custom gas token ERC20's, which won't be the native token
// on the L2 by definition.
// Native token expected to be sent in L2 message. Should be 0 for most use cases of this constant. This
// constant is unused when sending the native gas token over the inbox since the inbox interprets `l2CallValue`
// as the amount of the L2 native token to send.
uint256 public constant L2_CALL_VALUE = 0;

// Gas limit for L2 execution of a cross chain token transfer sent via the inbox.
uint32 public constant RELAY_TOKENS_L2_GAS_LIMIT = 300_000;
// Gas limit for L2 execution of a message sent via the inbox.
uint32 public constant RELAY_MESSAGE_L2_GAS_LIMIT = 2_000_000;

// The number of decimals of precision for the custom gas token. This is defined in the constructor and not dynamically fetched since decimals are
// not part of the standard ERC20 interface.
uint8 public immutable NATIVE_TOKEN_DECIMALS;

Check warning on line 66 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 66 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// This address on L2 receives extra gas token that is left over after relaying a message via the inbox.
address public immutable L2_REFUND_L2_ADDRESS;

Check warning on line 69 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 69 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// Inbox system contract to send messages to Arbitrum. Token bridges use this to send tokens to L2.
// https://github.com/OffchainLabs/nitro-contracts/blob/f7894d3a6d4035ba60f51a7f1334f0f2d4f02dce/src/bridge/Inbox.sol
ArbitrumL1InboxLike public immutable L1_INBOX;

Check warning on line 73 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 73 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// Router contract to send tokens to Arbitrum. Routes to correct gateway to bridge tokens. Internally this
// contract calls the Inbox.
// Generic gateway: https://github.com/OffchainLabs/token-bridge-contracts/blob/main/contracts/tokenbridge/ethereum/gateway/L1ArbitrumGateway.sol
// Gateway used for communicating with chains that use custom gas tokens:
// https://github.com/OffchainLabs/token-bridge-contracts/blob/main/contracts/tokenbridge/ethereum/gateway/L1ERC20Gateway.sol
ArbitrumL1ERC20GatewayLike public immutable L1_ERC20_GATEWAY_ROUTER;

Check warning on line 80 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 80 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// This token is used to pay for l1 to l2 messages if its configured by an Arbitrum orbit chain.
IERC20 public immutable CUSTOM_GAS_TOKEN;

Check warning on line 83 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

Check warning on line 83 in contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol

View workflow job for this annotation

GitHub Actions / Lint (20)

Variable name must be in mixedCase

// Contract that funds Inbox cross chain messages with the custom gas token.
FunderInterface public immutable CUSTOM_GAS_TOKEN_FUNDER;
Expand Down Expand Up @@ -104,10 +108,12 @@
address _l2RefundL2Address,
IERC20 _l1Usdc,
ICCTPTokenMessenger _cctpTokenMessenger,
uint32 _circleDomainId,
FunderInterface _customGasTokenFunder,
uint8 _nativeTokenDecimals,
uint256 _l2MaxSubmissionCost,
uint256 _l2GasPrice
) CircleCCTPAdapter(_l1Usdc, _cctpTokenMessenger, CircleDomainIds.Arbitrum) {
) CircleCCTPAdapter(_l1Usdc, _cctpTokenMessenger, _circleDomainId) {
L1_INBOX = _l1ArbitrumInbox;
L1_ERC20_GATEWAY_ROUTER = _l1ERC20GatewayRouter;
L2_REFUND_L2_ADDRESS = _l2RefundL2Address;
Expand All @@ -116,6 +122,7 @@
L2_MAX_SUBMISSION_COST = _l2MaxSubmissionCost;
L2_GAS_PRICE = _l2GasPrice;
CUSTOM_GAS_TOKEN_FUNDER = _customGasTokenFunder;
NATIVE_TOKEN_DECIMALS = _nativeTokenDecimals;
pxrl marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down Expand Up @@ -177,7 +184,7 @@
CUSTOM_GAS_TOKEN.safeIncreaseAllowance(address(L1_INBOX), amountToBridge);
L1_INBOX.createRetryableTicket(
to, // destAddr destination L2 contract address
L2_CALL_VALUE, // l2CallValue call value for retryable L2 message
amount, // l2CallValue call value for retryable L2 message
L2_MAX_SUBMISSION_COST, // maxSubmissionCost Max gas deducted from user's L2 balance to cover base fee
L2_REFUND_L2_ADDRESS, // excessFeeRefundAddress maxgas * gasprice - execution cost gets credited here on L2
L2_REFUND_L2_ADDRESS, // callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
Expand Down Expand Up @@ -226,12 +233,11 @@
}

function _from18ToNativeDecimals(uint256 amount) internal view returns (uint256) {
uint8 nativeTokenDecimals = L1_INBOX.bridge().nativeTokenDecimals();
if (nativeTokenDecimals == 18) {
if (NATIVE_TOKEN_DECIMALS == 18) {
return amount;
} else if (nativeTokenDecimals < 18) {
} else if (NATIVE_TOKEN_DECIMALS < 18) {
// Round up the division result so that the L1 call value is always sufficient to cover the submission fee.
uint256 reductionFactor = 10**(18 - nativeTokenDecimals);
uint256 reductionFactor = 10**(18 - NATIVE_TOKEN_DECIMALS);
uint256 divFloor = amount / reductionFactor;
uint256 mod = amount % reductionFactor;
if (mod != 0) {
Expand All @@ -240,7 +246,7 @@
return divFloor;
}
} else {
return amount * 10**(nativeTokenDecimals - 18);
return amount * 10**(NATIVE_TOKEN_DECIMALS - 18);
}
}
}
16 changes: 16 additions & 0 deletions deploy/052_deploy_donation_box.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployer } = await hre.getNamedAccounts();

await hre.deployments.deploy("DonationBox", {
contract: "DonationBox",
from: deployer,
log: true,
skipIfAlreadyDeployed: true,
args: [],
});
};
module.exports = func;
func.tags = ["DonationBox"];
35 changes: 35 additions & 0 deletions deploy/053_deploy_alephzero_adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { L1_ADDRESS_MAP, ZERO_ADDRESS, AZERO, ARBITRUM_MAX_SUBMISSION_COST, AZERO_GAS_PRICE } from "./consts";
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployer } = await hre.getNamedAccounts();
const chainId = parseInt(await hre.getChainId());

// This address receives gas refunds on the L2 after messages are relayed. Currently
// set to the Risk Labs relayer address. The deployer should change this if necessary.
const l2RefundAddress = "0x07aE8551Be970cB1cCa11Dd7a11F47Ae82e70E67";

const args = [
L1_ADDRESS_MAP[chainId].l1AlephZeroInbox,
L1_ADDRESS_MAP[chainId].l1AlephZeroERC20GatewayRouter,
l2RefundAddress,
ZERO_ADDRESS,
ZERO_ADDRESS,
0, // No Circle CCTP domain ID.
L1_ADDRESS_MAP[chainId].donationBox,
AZERO.decimals,
ARBITRUM_MAX_SUBMISSION_COST,
AZERO_GAS_PRICE,
];
const instance = await hre.deployments.deploy("Arbitrum_CustomGasToken_Adapter", {
from: deployer,
log: true,
skipIfAlreadyDeployed: false,
args,
});
await hre.run("verify:verify", { address: instance.address, constructorArguments: args });
};

module.exports = func;
func.tags = ["ArbitrumCustomGasTokenAdapter", "mainnet"];
6 changes: 6 additions & 0 deletions deploy/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../utils";
export const USDC = TOKEN_SYMBOLS_MAP.USDC.addresses;
export const WETH = TOKEN_SYMBOLS_MAP.WETH.addresses;
export const WMATIC = TOKEN_SYMBOLS_MAP.WMATIC.addresses;
export const AZERO = TOKEN_SYMBOLS_MAP.AZERO;

export const QUOTE_TIME_BUFFER = 3600;
export const FILL_DEADLINE_BUFFER = 6 * 3600;
export const ARBITRUM_MAX_SUBMISSION_COST = "10000000000000000";
export const AZERO_GAS_PRICE = "240000000000";

export const L1_ADDRESS_MAP: { [key: number]: { [contractName: string]: string } } = {
[CHAIN_IDs.MAINNET]: {
Expand Down Expand Up @@ -48,6 +51,9 @@ export const L1_ADDRESS_MAP: { [key: number]: { [contractName: string]: string }
zoraStandardBridge: "0x3e2Ea9B92B7E48A52296fD261dc26fd995284631",
worldChainCrossDomainMessenger: "0xf931a81D18B1766d15695ffc7c1920a62b7e710a",
worldChainStandardBridge: "0x470458C91978D2d929704489Ad730DC3E3001113",
l1AlephZeroInbox: "0x56D8EC76a421063e1907503aDd3794c395256AEb",
l1AlephZeroERC20GatewayRouter: "0xeBb17f398ed30d02F2e8733e7c1e5cf566e17812",
donationBox: "0x90285a96F5955A7279EF0C1e89A1B4f66d8E4dA7",
},
[CHAIN_IDs.SEPOLIA]: {
optimismCrossDomainMessenger: "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"prepublish": "yarn build && hardhat export --export-all ./cache/massExport.json && ts-node ./scripts/processHardhatExport.ts && prettier --write ./deployments/deployments.json && yarn generate-contract-types"
},
"dependencies": {
"@across-protocol/constants": "^3.1.16",
"@across-protocol/constants": "^3.1.17",
"@coral-xyz/anchor": "^0.30.1",
"@defi-wonderland/smock": "^2.3.4",
"@eth-optimism/contracts": "^0.5.40",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# yarn lockfile v1


"@across-protocol/constants@^3.1.16":
version "3.1.16"
resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.16.tgz#c126085d29d4d051fd02a04c833d804d37c3c219"
integrity sha512-+U+AecGWnfY4b4sSfKBvsDj/+yXKEqpTXcZgI8GVVmUTkUhs1efA0kN4q3q10yy5TXI5TtagaG7R9yZg1zgKKg==
"@across-protocol/constants@^3.1.17":
version "3.1.17"
resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.17.tgz#1e43c87fbab06df3a1aab8993d7c5f746838e25d"
integrity sha512-mW++45vP04ahogsHFM5nE7ZKV8vmdxSO8gbBeP24VFxijrIYWqhISG67EU9pnAbgAIB58pT+ZmqdXI25iDmctA==

"@across-protocol/contracts@^0.1.4":
version "0.1.4"
Expand Down
Loading