Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 into zksync
  • Loading branch information
nicholaspai committed Jul 10, 2023
2 parents f559eff + 3634df5 commit 2cea86d
Show file tree
Hide file tree
Showing 155 changed files with 5,778 additions and 1,611 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ cache
coverage*
gasReporterOutput.json
typechain
artifacts-zk
cache-zk
50 changes: 48 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# When making a release, please keep in mind that this action expects and validates a few things:
# - Releases marked as drafts will be ignored (ie. they will not publish).
# - Ensure that package.json has a version.
# - Ensure the git tag you create during the release process starts with a v (ie. v1.2.3).
# - Ensure that the version in package.json matches the release tag created.
# - Ensure versions are valid semver format.
# - Ensure the GitHub release is marked as a pre-release if the semver version has a pre-release tag.

# This script was inspired by this README: https://github.com/marketplace/actions/github-releases-for-automated-package-publishing

name: Publish Package to npmjs
on:
release:
Expand All @@ -7,12 +17,48 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

# Note we set an `id` called `release`. We'll use that later...
- name: Validate and extract release information
id: release
uses: manovotny/[email protected]

# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: "16.x"
always-auth: true
registry-url: "https://registry.npmjs.org"

# Perform installs, run tests, run a build step, etc. here, as needed.
- run: yarn
- run: yarn publish

# The last two steps will publish the package. Note that we're using
# information from the `release` step above (I told you we'd use it
# later). Notice the `if` statements on both steps...
#
# If there *is* a tag (ie. `beta`, `canary`, etc.), we publish a
# "pre-release" or "tagged" version of a package (ie. 1.2.3-beta.1).
#
# If there *is not* a tag (ie. `beta`, `canary`, etc.), we publish a
# version of a package (ie. 1.2.3).
#
# This example is using npm to publish, but you could just as easily
# use yarn, if you prefer. It's also publishing to the NPM registry,
# thus, it's using `NPM_TOKEN`, but you could just as easily use
# `GITHUB_TOKEN` if you were publishing to the GitHub Package registry.

# This will publish a "pre-release" or "tagged" version of a package.

# This will publish a version of a package.
- name: Publish version
if: steps.release.outputs.tag == ''
run: yarn publish
env:
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish tagged version
if: steps.release.outputs.tag != ''
run: yarn publish --tag ${{ steps.release.outputs.tag }}
env:
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
hardhat.config.ts
cache
cache-zk
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ coverage*
gasReporterOutput.json
typechain
dist
artifacts-zk
cache-zk
702 changes: 70 additions & 632 deletions LICENSE

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,10 @@ These are special instructions for compiling and deploying contracts on `zksync`
This step requires [Docker Desktop](https://www.docker.com/products/docker-desktop/) to be running, as the `solc` docker image is fetched as a prerequisite.

`yarn compile-zksync`

## License

All code in this repository is licensed under BUSL-1.1 unless specified differently in the file.
Individual exceptions to this license can be made by Risk Labs, which holds the rights to this
software and design. If you are interested in using the code or designs in a derivative work,
feel free to reach out to [email protected].
2 changes: 1 addition & 1 deletion contracts/AcrossConfigStore.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "@uma/core/contracts/common/implementation/MultiCaller.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/Arbitrum_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./SpokePool.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/Boba_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./Ovm_SpokePool.sol";
Expand Down
8 changes: 4 additions & 4 deletions contracts/BondToken.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";

import "./HubPoolInterface.sol";
import "./interfaces/HubPoolInterface.sol";
import "./external/WETH9.sol";

interface ExtendedHubPoolInterface is HubPoolInterface {
// Specify the automatically-implemented rootBundleProposer() getter.
// Specify the automatically-implemented rootBundleProposal() getter.
function rootBundleProposal() external pure returns (HubPoolInterface.RootBundle memory);
}

Expand All @@ -18,7 +18,7 @@ interface ExtendedHubPoolInterface is HubPoolInterface {
* imposes address-based permissioning on the WETH9 transferFrom() function in order to constrain the movement of ABT
* into the Across v2 HubPool contract. When configured as the required HubPool bond token, ABT can dramatically reduce
* the attack surface of the HubPool by requiring that addresses are explicitly approved before they can successfully
* submit a root bundle proposal. The address-based permissiong does not constrain transfers that are needed to dispute
* submit a root bundle proposal. The address-based permissioning does not constrain transfers that are needed to dispute
* a root bundle proposal, so the ability of decentralised/unknown actors to dispute is unaffected.
*/
contract BondToken is WETH9, Ownable {
Expand Down
2 changes: 1 addition & 1 deletion contracts/Ethereum_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./SpokePool.sol";
Expand Down
6 changes: 3 additions & 3 deletions contracts/HubPool.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./MerkleLib.sol";
import "./HubPoolInterface.sol";
import "./interfaces/HubPoolInterface.sol";
import "./Lockable.sol";

import "./interfaces/LpTokenFactoryInterface.sol";
import "./interfaces/WETH9Interface.sol";
import "./external/interfaces/WETH9Interface.sol";

import "@uma/core/contracts/common/implementation/Testable.sol";
import "@uma/core/contracts/common/implementation/MultiCaller.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/Lockable.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

/**
Expand Down
2 changes: 1 addition & 1 deletion contracts/LpTokenFactory.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./interfaces/LpTokenFactoryInterface.sol";
Expand Down
8 changes: 4 additions & 4 deletions contracts/MerkleLib.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./SpokePoolInterface.sol";
import "./HubPoolInterface.sol";
import "./interfaces/SpokePoolInterface.sol";
import "./interfaces/HubPoolInterface.sol";

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

Expand Down Expand Up @@ -102,6 +102,6 @@ library MerkleLib {
* @return uint256 representing the modified input claimedBitMap with the index set to true.
*/
function setClaimed1D(uint256 claimedBitMap, uint8 index) internal pure returns (uint256) {
return claimedBitMap | (1 << index % 256);
return claimedBitMap | (1 << index);
}
}
2 changes: 1 addition & 1 deletion contracts/Optimism_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";

Expand Down
35 changes: 30 additions & 5 deletions contracts/Ovm_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./SpokePool.sol";
import "./interfaces/WETH9Interface.sol";
import "./external/interfaces/WETH9Interface.sol";

import "@openzeppelin/contracts-upgradeable/crosschain/optimism/LibOptimismUpgradeable.sol";
import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import "@eth-optimism/contracts/L2/messaging/IL2ERC20Bridge.sol";

// https://github.com/Synthetixio/synthetix/blob/5ca27785fad8237fb0710eac01421cafbbd69647/contracts/SynthetixBridgeToBase.sol#L50
interface SynthetixBridgeToBase {
function withdrawTo(address to, uint256 amount) external;
}

// https://github.com/ethereum-optimism/optimism/blob/bf51c4935261634120f31827c3910aa631f6bf9c/packages/contracts-bedrock/contracts/L2/L2StandardBridge.sol
interface IL2ERC20Bridge {
function withdrawTo(
address _l2Token,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable;
}

/**
* @notice OVM specific SpokePool. Uses OVM cross-domain-enabled logic to implement admin only access to functions. * Optimism and Boba each implement this spoke pool and set their chain specific contract addresses for l2Eth and l2Weth.
*/
Expand All @@ -27,6 +37,12 @@ contract Ovm_SpokePool is SpokePool {
// Address of the Optimism L2 messenger.
address public messenger;

// Address of custom bridge used to bridge Synthetix-related assets like SNX.
address private constant SYNTHETIX_BRIDGE = 0x136b1EC699c62b0606854056f02dC7Bb80482d63;

// Address of SNX ERC20
address private constant SNX = 0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4;

// Stores alternative token bridges to use for L2 tokens that don't go over the standard bridge. This is needed
// to support non-standard ERC20 tokens on Optimism, such as DIA and SNX which both use custom bridges.
mapping(address => address) public tokenBridges;
Expand Down Expand Up @@ -155,10 +171,19 @@ contract Ovm_SpokePool is SpokePool {
if (relayerRefundLeaf.l2TokenAddress == address(wrappedNativeToken)) {
WETH9Interface(relayerRefundLeaf.l2TokenAddress).withdraw(relayerRefundLeaf.amountToReturn); // Unwrap into ETH.
relayerRefundLeaf.l2TokenAddress = l2Eth; // Set the l2TokenAddress to ETH.
IL2ERC20Bridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo{
value: relayerRefundLeaf.amountToReturn
}(
relayerRefundLeaf.l2TokenAddress, // _l2Token. Address of the L2 token to bridge over.
hubPool, // _to. Withdraw, over the bridge, to the l1 pool contract.
relayerRefundLeaf.amountToReturn, // _amount.
l1Gas, // _l1Gas. Unused, but included for potential forward compatibility considerations
"" // _data. We don't need to send any data for the bridging action.
);
}
// Handle custom SNX bridge which doesn't conform to the standard bridge interface.
if (relayerRefundLeaf.l2TokenAddress == 0x8700dAec35aF8Ff88c16BdF0418774CB3D7599B4)
SynthetixBridgeToBase(0x136b1EC699c62b0606854056f02dC7Bb80482d63).withdrawTo(
else if (relayerRefundLeaf.l2TokenAddress == SNX)
SynthetixBridgeToBase(SYNTHETIX_BRIDGE).withdrawTo(
hubPool, // _to. Withdraw, over the bridge, to the l1 pool contract.
relayerRefundLeaf.amountToReturn // _amount.
);
Expand Down
4 changes: 2 additions & 2 deletions contracts/PolygonTokenBridger.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./Lockable.sol";
import "./interfaces/WETH9Interface.sol";
import "./external/interfaces/WETH9Interface.sol";

import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
Expand Down
30 changes: 23 additions & 7 deletions contracts/Polygon_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
// SPDX-License-Identifier: GPL-3.0-only
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import "./SpokePool.sol";
import "./PolygonTokenBridger.sol";
import "./interfaces/WETH9Interface.sol";
import "./SpokePoolInterface.sol";
import "./external/interfaces/WETH9Interface.sol";
import "./interfaces/SpokePoolInterface.sol";

// IFxMessageProcessor represents interface to process messages.
/**
* @notice IFxMessageProcessor represents interface to process messages.
*/
interface IFxMessageProcessor {
/**
* @notice Called by FxChild upon receiving L1 message that targets this contract. Performs an additional check
* that the L1 caller was the expected cross domain admin, and then delegate calls.
* @notice Polygon bridge only executes this external function on the target Polygon contract when relaying
* messages from L1, so all functions on this SpokePool are expected to originate via this call.
* @dev stateId value isn't used because it isn't relevant for this method. It doesn't care what state sync
* triggered this call.
* @param rootMessageSender Original L1 sender of data.
* @param data ABI encoded function call to execute on this contract.
*/
function processMessageFromRoot(
uint256 stateId,
address rootMessageSender,
Expand Down Expand Up @@ -35,6 +47,7 @@ contract Polygon_SpokePool is IFxMessageProcessor, SpokePool {
event PolygonTokensBridged(address indexed token, address indexed receiver, uint256 amount);
event SetFxChild(address indexed newFxChild);
event SetPolygonTokenBridger(address indexed polygonTokenBridger);
event ReceivedMessageFromL1(address indexed caller, address indexed rootMessageSender);

// Note: validating calls this way ensures that strange calls coming from the fxChild won't be misinterpreted.
// Put differently, just checking that msg.sender == fxChild is not sufficient.
Expand All @@ -48,7 +61,7 @@ contract Polygon_SpokePool is IFxMessageProcessor, SpokePool {

// This sets a variable indicating that we're now inside a validated call.
// Note: this is used by other methods to ensure that this call has been validated by this method and is not
// spoofed. See
// spoofed. See comment for `_requireAdminSender` for more details.
callValidated = true;

_;
Expand Down Expand Up @@ -132,12 +145,15 @@ contract Polygon_SpokePool is IFxMessageProcessor, SpokePool {
(bool success, ) = address(this).delegatecall(data);
//slither-disable-end low-level-calls
require(success, "delegatecall failed");

emit ReceivedMessageFromL1(msg.sender, rootMessageSender);
}

/**
* @notice Allows the caller to trigger the wrapping of any unwrapped matic tokens.
* @dev Matic sends via L1 -> L2 bridging actions don't call into the contract receiving the tokens, so wrapping
* must be done via a separate transaction.
* @dev Unlike other ERC20 transfers, Matic transfers from L1 -> L2 bridging don't result in an L2 call into
* the contract receiving the tokens, so wrapping must be done via a separate transaction. In other words,
* we can't rely upon a `fallback()` method being triggered to wrap MATIC upon receiving it.
*/
function wrap() public nonReentrant {
_wrap();
Expand Down
Loading

0 comments on commit 2cea86d

Please sign in to comment.