Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c8bc78d
feat: Add NatSpec
nicholaspai Feb 28, 2022
f39201e
Merge branch 'master' of https://github.com/across-protocol/across-sm…
nicholaspai Feb 28, 2022
1a92ce9
Update README.md
nicholaspai Feb 28, 2022
2a4757b
Update README.md
nicholaspai Feb 28, 2022
fae2205
Update README.md
nicholaspai Feb 28, 2022
8fc835a
Update README.md
nicholaspai Feb 28, 2022
0f8147d
Update README.md
nicholaspai Feb 28, 2022
cf8a8ce
Update HubPool.sol
nicholaspai Feb 28, 2022
6e6c463
Merge branch 'npai/natspec' of https://github.com/across-protocol/acr…
nicholaspai Feb 28, 2022
d158ef6
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
2952b1d
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
2d675a7
Update HubPool.sol
nicholaspai Feb 28, 2022
159ecea
Merge branch 'npai/natspec' of https://github.com/across-protocol/acr…
nicholaspai Feb 28, 2022
e5297a2
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
7737389
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
7920060
Update HubPool.sol
nicholaspai Feb 28, 2022
01bf8ba
Merge branch 'npai/natspec' of https://github.com/across-protocol/acr…
nicholaspai Feb 28, 2022
00424a8
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
050f400
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
7b3f77d
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
2bc04bb
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
8c3d1b0
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
b6198d1
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
9432c80
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
9fb9e8b
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
05f490b
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
be69980
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
377f3dc
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
ef61688
Update HubPool.sol
nicholaspai Feb 28, 2022
ea269d6
Merge branch 'npai/natspec' of https://github.com/across-protocol/acr…
nicholaspai Feb 28, 2022
cfb51bc
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
d2fa9a9
Update contracts/HubPool.sol
nicholaspai Feb 28, 2022
95824de
Update HubPool.sol
nicholaspai Feb 28, 2022
2f0b837
Merge branch 'npai/natspec' of https://github.com/across-protocol/acr…
nicholaspai Feb 28, 2022
ee704c6
Update Ethereum_Adapter.sol
nicholaspai Feb 28, 2022
14f12d0
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
975f7d0
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
babb7ee
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
d8eac06
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
4d241f2
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
69e67c6
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
598efdb
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
9a83495
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
ae8b3d9
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
aae3977
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
767a91e
Update contracts/SpokePool.sol
nicholaspai Feb 28, 2022
0fff462
nit
Mar 1, 2022
71b1024
nit
chrismaree Mar 1, 2022
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
52 changes: 22 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
# Advanced Sample Hardhat Project
![Across-logo](https://raw.githubusercontent.com/across-protocol/across-frontend/65abd7772704a9ec243fd370f9e8e76322f0905b/src/assets/logo.svg)

This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the ecosystem.
Contains smart contract suite to enable instant token transfers between any two networks. Relays are backstopped by
liquidity held in a central `HubPool` on Ethereum, which also serves as the cross-chain administrator of all contracts in the
system. `SpokePool` contracts are deployed to any network that wants to originate token deposits or be the final
destination for token transfers, and they are all governed by the `HubPool` on Ethereum.

The project comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts. It also comes with a variety of other tools, preconfigured to work with the project code.
This contract set is the second iteration of the [Across smart contracts](https://github.com/across-protocol/across-smart-contracts)
which facilitate token transfers from any L2 to L1.

Try running some of the following tasks:
## Build

```shell
npx hardhat accounts
npx hardhat compile
npx hardhat clean
npx hardhat test
npx hardhat node
npx hardhat help
REPORT_GAS=true npx hardhat test
npx hardhat coverage
npx hardhat run scripts/deploy.ts
TS_NODE_FILES=true npx ts-node scripts/deploy.ts
npx eslint '**/*.{js,ts}'
npx eslint '**/*.{js,ts}' --fix
npx prettier '**/*.{json,sol,md}' --check
npx prettier '**/*.{json,sol,md}' --write
npx solhint 'contracts/**/*.sol'
npx solhint 'contracts/**/*.sol' --fix
yarn
yarn hardhat compile
```

# Etherscan verification

To try out Etherscan verification, you first need to deploy a contract to an Ethereum network that's supported by Etherscan, such as Ropsten.

In this project, copy the .env.example file to a file named .env, and then edit it to fill in the details. Enter your Etherscan API key, your Ropsten node URL (eg from Alchemy), and the private key of the account which will send the deployment transaction. With a valid .env file in place, first deploy your contract:
## Test

```shell
hardhat run --network ropsten scripts/sample-script.ts
yarn test # Run unit tests without gas analysis
yarn test:gas-analytics # Run only tests that count gas costs
yarn test:report-gas # Run unit tests with hardhat-gas-reporter enabled
```

Then, copy the deployment address and paste it in to replace `DEPLOYED_CONTRACT_ADDRESS` in this command:
## Lint

```shell
npx hardhat verify --network ropsten DEPLOYED_CONTRACT_ADDRESS "Hello, Hardhat!"
yarn lint
yarn lint-fix
```

# Performance optimizations
## Deploy and Verify

For faster runs of your tests and scripts, consider skipping ts-node's type checking by setting the environment variable `TS_NODE_TRANSPILE_ONLY` to `1` in hardhat's environment. For more details see [the documentation](https://hardhat.org/guides/typescript.html#performance-optimizations).
```shell
NODE_URL_1=https://mainnet.infura.com/xxx yarn hardhat deploy --tags HubPool --network mainnet
ETHERSCAN_API_KEY=XXX yarn hardhat etherscan-verify --network mainnet --license AGPL-3.0 --force-license --solc-input
```
37 changes: 27 additions & 10 deletions contracts/Arbitrum_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//SPDX-License-Identifier: Unlicense
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "./SpokePool.sol";
Expand All @@ -14,22 +14,28 @@ interface StandardBridgeLike {
}

/**
* @notice AVM specific SpokePool.
* @dev Uses AVM cross-domain-enabled logic for access control.
* @notice AVM specific SpokePool. Uses AVM cross-domain-enabled logic to implement admin only access to functions.
*/

contract Arbitrum_SpokePool is SpokePoolInterface, SpokePool {
// Address of the Arbitrum L2 token gateway.
contract Arbitrum_SpokePool is SpokePool {
// Address of the Arbitrum L2 token gateway to send funds to L1.
address public l2GatewayRouter;

// Admin controlled mapping of arbitrum tokens to L1 counterpart. L1 counterpart addresses
// are neccessary to bridge tokens to L1.
// are neccessary params used when bridging tokens to L1.
mapping(address => address) public whitelistedTokens;

event ArbitrumTokensBridged(address indexed l1Token, address target, uint256 numberOfTokensBridged);
event SetL2GatewayRouter(address indexed newL2GatewayRouter);
event WhitelistedTokens(address indexed l2Token, address indexed l1Token);

/**
* @notice Construct the AVM SpokePool.
* @param _l2GatewayRouter Address of L2 token gateway. Can be reset by admin.
* @param _crossDomainAdmin Cross domain admin to set. Can be changed by admin.
* @param _hubPool Hub pool address to set. Can be changed by admin.
* @param _wethAddress Weth address for this network to set.
* @param timerAddress Timer address to set.
*/
constructor(
address _l2GatewayRouter,
address _crossDomainAdmin,
Expand All @@ -49,10 +55,19 @@ contract Arbitrum_SpokePool is SpokePoolInterface, SpokePool {
* ARBITRUM-SPECIFIC CROSS-CHAIN ADMIN FUNCTIONS *
********************************************************/

/**
* @notice Change L2 gateway router. Callable only by admin.
* @param newL2GatewayRouter New L2 gateway router.
*/
function setL2GatewayRouter(address newL2GatewayRouter) public onlyAdmin nonReentrant {
_setL2GatewayRouter(newL2GatewayRouter);
}

/**
* @notice Add L2 -> L1 token mapping. Callable only by admin.
* @param l2Token Arbitrum token.
* @param l1Token Ethereum version of l2Token.
*/
function whitelistToken(address l2Token, address l1Token) public onlyAdmin nonReentrant {
_whitelistToken(l2Token, l1Token);
}
Expand Down Expand Up @@ -81,15 +96,17 @@ contract Arbitrum_SpokePool is SpokePoolInterface, SpokePool {
emit WhitelistedTokens(_l2Token, _l1Token);
}

// l1 addresses are transformed during l1->l2 calls. See https://developer.offchainlabs.com/docs/l1_l2_messages#address-aliasing for more information.
// This cannot be pulled directly from Arbitrum contracts because their contracts are not 0.8.X compatible and this operation takes advantage of
// overflows, whose behavior changed in 0.8.0.
// L1 addresses are transformed during l1->l2 calls.
// See https://developer.offchainlabs.com/docs/l1_l2_messages#address-aliasing for more information.
// This cannot be pulled directly from Arbitrum contracts because their contracts are not 0.8.X compatible and
// this operation takes advantage of overflows, whose behavior changed in 0.8.0.
function _applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {
// Allows overflows as explained above.
unchecked {
l2Address = address(uint160(l1Address) + uint160(0x1111000000000000000000000000000000001111));
}
}

// Apply AVM-specific transformation to cross domain admin address on L1.
function _requireAdminSender() internal override onlyFromCrossDomainAdmin {}
}
16 changes: 11 additions & 5 deletions contracts/Ethereum_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//SPDX-License-Identifier: Unlicense
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "./interfaces/WETH9.sol";
Expand All @@ -10,11 +10,15 @@ import "./SpokePool.sol";
import "./SpokePoolInterface.sol";

/**
* @notice Ethereum L1 specific SpokePool.
* @dev Used on Ethereum L1 to facilitate L2->L1 transfers.
* @notice Ethereum L1 specific SpokePool. Used on Ethereum L1 to facilitate L2->L1 transfers.
*/

contract Ethereum_SpokePool is SpokePoolInterface, SpokePool, Ownable {
contract Ethereum_SpokePool is SpokePool, Ownable {
/**
* @notice Construct the Ethereum SpokePool.
* @param _hubPool Hub pool address to set. Can be changed by admin.
* @param _wethAddress Weth address for this network to set.
* @param timerAddress Timer address to set.
*/
constructor(
address _hubPool,
address _wethAddress,
Expand All @@ -29,5 +33,7 @@ contract Ethereum_SpokePool is SpokePoolInterface, SpokePool, Ownable {
IERC20(relayerRefundLeaf.l2TokenAddress).transfer(hubPool, relayerRefundLeaf.amountToReturn);
}

// Admin is simply owner which should be same account that owns the HubPool deployed on this network. A core
// assumption of this contract system is that the HubPool is deployed on Ethereum.
function _requireAdminSender() internal override onlyOwner {}
}
Loading