编译器
0.6.12+commit.27d51765
文件 1 的 8:Accounting.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
abstract contract Accounting is ReentrancyGuard {
using SafeMath for uint256;
mapping(address => bool) private _isBonder;
mapping(address => uint256) private _credit;
mapping(address => uint256) private _debit;
event Stake (
address indexed account,
uint256 amount
);
event Unstake (
address indexed account,
uint256 amount
);
event BonderAdded (
address indexed newBonder
);
event BonderRemoved (
address indexed previousBonder
);
modifier onlyBonder {
require(_isBonder[msg.sender], "ACT: Caller is not bonder");
_;
}
modifier onlyGovernance {
_requireIsGovernance();
_;
}
modifier requirePositiveBalance {
_;
require(getCredit(msg.sender) >= getDebitAndAdditionalDebit(msg.sender), "ACT: Not enough available credit");
}
constructor(address[] memory bonders) public {
for (uint256 i = 0; i < bonders.length; i++) {
require(_isBonder[bonders[i]] == false, "ACT: Cannot add duplicate bonder");
_isBonder[bonders[i]] = true;
emit BonderAdded(bonders[i]);
}
}
function _transferFromBridge(address recipient, uint256 amount) internal virtual;
function _transferToBridge(address from, uint256 amount) internal virtual;
function _requireIsGovernance() internal virtual;
function _additionalDebit(address ) internal view virtual returns (uint256) {
this;
return 0;
}
function getIsBonder(address maybeBonder) public view returns (bool) {
return _isBonder[maybeBonder];
}
function getCredit(address bonder) public view returns (uint256) {
return _credit[bonder];
}
function getRawDebit(address bonder) external view returns (uint256) {
return _debit[bonder];
}
function getDebitAndAdditionalDebit(address bonder) public view returns (uint256) {
return _debit[bonder].add(_additionalDebit(bonder));
}
function stake(address bonder, uint256 amount) external payable nonReentrant {
require(_isBonder[bonder] == true, "ACT: Address is not bonder");
_transferToBridge(msg.sender, amount);
_addCredit(bonder, amount);
emit Stake(bonder, amount);
}
function unstake(uint256 amount) external requirePositiveBalance nonReentrant {
_addDebit(msg.sender, amount);
_transferFromBridge(msg.sender, amount);
emit Unstake(msg.sender, amount);
}
function addBonder(address bonder) external onlyGovernance {
require(_isBonder[bonder] == false, "ACT: Address is already bonder");
_isBonder[bonder] = true;
emit BonderAdded(bonder);
}
function removeBonder(address bonder) external onlyGovernance {
require(_isBonder[bonder] == true, "ACT: Address is not bonder");
_isBonder[bonder] = false;
emit BonderRemoved(bonder);
}
function _addCredit(address bonder, uint256 amount) internal {
_credit[bonder] = _credit[bonder].add(amount);
}
function _addDebit(address bonder, uint256 amount) internal {
_debit[bonder] = _debit[bonder].add(amount);
}
}
文件 2 的 8:Bridge.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "./Accounting.sol";
import "../libraries/Lib_MerkleTree.sol";
abstract contract Bridge is Accounting {
using Lib_MerkleTree for bytes32;
struct TransferRoot {
uint256 total;
uint256 amountWithdrawn;
uint256 createdAt;
}
event Withdrew(
bytes32 indexed transferId,
address indexed recipient,
uint256 amount,
bytes32 transferNonce
);
event WithdrawalBonded(
bytes32 indexed transferId,
uint256 amount
);
event WithdrawalBondSettled(
address indexed bonder,
bytes32 indexed transferId,
bytes32 indexed rootHash
);
event MultipleWithdrawalsSettled(
address indexed bonder,
bytes32 indexed rootHash,
uint256 totalBondsSettled
);
event TransferRootSet(
bytes32 indexed rootHash,
uint256 totalAmount
);
mapping(bytes32 => TransferRoot) private _transferRoots;
mapping(bytes32 => bool) private _spentTransferIds;
mapping(address => mapping(bytes32 => uint256)) private _bondedWithdrawalAmounts;
uint256 constant RESCUE_DELAY = 8 weeks;
constructor(address[] memory bonders) public Accounting(bonders) {}
function getTransferId(
uint256 chainId,
address recipient,
uint256 amount,
bytes32 transferNonce,
uint256 bonderFee,
uint256 amountOutMin,
uint256 deadline
)
public
pure
returns (bytes32)
{
return keccak256(abi.encode(
chainId,
recipient,
amount,
transferNonce,
bonderFee,
amountOutMin,
deadline
));
}
function getChainId() public virtual view returns (uint256 chainId) {
this;
assembly {
chainId := chainid()
}
}
function getTransferRootId(bytes32 rootHash, uint256 totalAmount) public pure returns (bytes32) {
return keccak256(abi.encodePacked(rootHash, totalAmount));
}
function getTransferRoot(bytes32 rootHash, uint256 totalAmount) public view returns (TransferRoot memory) {
return _transferRoots[getTransferRootId(rootHash, totalAmount)];
}
function getBondedWithdrawalAmount(address bonder, bytes32 transferId) external view returns (uint256) {
return _bondedWithdrawalAmounts[bonder][transferId];
}
function isTransferIdSpent(bytes32 transferId) external view returns (bool) {
return _spentTransferIds[transferId];
}
function withdraw(
address recipient,
uint256 amount,
bytes32 transferNonce,
uint256 bonderFee,
uint256 amountOutMin,
uint256 deadline,
bytes32 rootHash,
uint256 transferRootTotalAmount,
uint256 transferIdTreeIndex,
bytes32[] calldata siblings,
uint256 totalLeaves
)
external
nonReentrant
{
bytes32 transferId = getTransferId(
getChainId(),
recipient,
amount,
transferNonce,
bonderFee,
amountOutMin,
deadline
);
require(
rootHash.verify(
transferId,
transferIdTreeIndex,
siblings,
totalLeaves
)
, "BRG: Invalid transfer proof");
bytes32 transferRootId = getTransferRootId(rootHash, transferRootTotalAmount);
_addToAmountWithdrawn(transferRootId, amount);
_fulfillWithdraw(transferId, recipient, amount, uint256(0));
emit Withdrew(transferId, recipient, amount, transferNonce);
}
function bondWithdrawal(
address recipient,
uint256 amount,
bytes32 transferNonce,
uint256 bonderFee
)
external
onlyBonder
requirePositiveBalance
nonReentrant
{
bytes32 transferId = getTransferId(
getChainId(),
recipient,
amount,
transferNonce,
bonderFee,
0,
0
);
_bondWithdrawal(transferId, amount);
_fulfillWithdraw(transferId, recipient, amount, bonderFee);
}
function settleBondedWithdrawal(
address bonder,
bytes32 transferId,
bytes32 rootHash,
uint256 transferRootTotalAmount,
uint256 transferIdTreeIndex,
bytes32[] calldata siblings,
uint256 totalLeaves
)
external
{
require(
rootHash.verify(
transferId,
transferIdTreeIndex,
siblings,
totalLeaves
)
, "BRG: Invalid transfer proof");
bytes32 transferRootId = getTransferRootId(rootHash, transferRootTotalAmount);
uint256 amount = _bondedWithdrawalAmounts[bonder][transferId];
require(amount > 0, "L2_BRG: transferId has no bond");
_bondedWithdrawalAmounts[bonder][transferId] = 0;
_addToAmountWithdrawn(transferRootId, amount);
_addCredit(bonder, amount);
emit WithdrawalBondSettled(bonder, transferId, rootHash);
}
function settleBondedWithdrawals(
address bonder,
bytes32[] calldata transferIds,
uint256 totalAmount
)
external
{
bytes32 rootHash = Lib_MerkleTree.getMerkleRoot(transferIds);
bytes32 transferRootId = getTransferRootId(rootHash, totalAmount);
uint256 totalBondsSettled = 0;
for(uint256 i = 0; i < transferIds.length; i++) {
uint256 transferBondAmount = _bondedWithdrawalAmounts[bonder][transferIds[i]];
if (transferBondAmount > 0) {
totalBondsSettled = totalBondsSettled.add(transferBondAmount);
_bondedWithdrawalAmounts[bonder][transferIds[i]] = 0;
}
}
_addToAmountWithdrawn(transferRootId, totalBondsSettled);
_addCredit(bonder, totalBondsSettled);
emit MultipleWithdrawalsSettled(bonder, rootHash, totalBondsSettled);
}
function rescueTransferRoot(bytes32 rootHash, uint256 originalAmount, address recipient) external onlyGovernance {
bytes32 transferRootId = getTransferRootId(rootHash, originalAmount);
TransferRoot memory transferRoot = getTransferRoot(rootHash, originalAmount);
require(transferRoot.createdAt != 0, "BRG: TransferRoot not found");
assert(transferRoot.total == originalAmount);
uint256 rescueDelayEnd = transferRoot.createdAt.add(RESCUE_DELAY);
require(block.timestamp >= rescueDelayEnd, "BRG: TransferRoot cannot be rescued before the Rescue Delay");
uint256 remainingAmount = transferRoot.total.sub(transferRoot.amountWithdrawn);
_addToAmountWithdrawn(transferRootId, remainingAmount);
_transferFromBridge(recipient, remainingAmount);
}
function _markTransferSpent(bytes32 transferId) internal {
require(!_spentTransferIds[transferId], "BRG: The transfer has already been withdrawn");
_spentTransferIds[transferId] = true;
}
function _addToAmountWithdrawn(bytes32 transferRootId, uint256 amount) internal {
TransferRoot storage transferRoot = _transferRoots[transferRootId];
require(transferRoot.total > 0, "BRG: Transfer root not found");
uint256 newAmountWithdrawn = transferRoot.amountWithdrawn.add(amount);
require(newAmountWithdrawn <= transferRoot.total, "BRG: Withdrawal exceeds TransferRoot total");
transferRoot.amountWithdrawn = newAmountWithdrawn;
}
function _setTransferRoot(bytes32 rootHash, uint256 totalAmount) internal {
bytes32 transferRootId = getTransferRootId(rootHash, totalAmount);
require(_transferRoots[transferRootId].total == 0, "BRG: Transfer root already set");
require(totalAmount > 0, "BRG: Cannot set TransferRoot totalAmount of 0");
_transferRoots[transferRootId] = TransferRoot(totalAmount, 0, block.timestamp);
emit TransferRootSet(rootHash, totalAmount);
}
function _bondWithdrawal(bytes32 transferId, uint256 amount) internal {
require(_bondedWithdrawalAmounts[msg.sender][transferId] == 0, "BRG: Withdrawal has already been bonded");
_addDebit(msg.sender, amount);
_bondedWithdrawalAmounts[msg.sender][transferId] = amount;
emit WithdrawalBonded(transferId, amount);
}
function _fulfillWithdraw(
bytes32 transferId,
address recipient,
uint256 amount,
uint256 bonderFee
) private {
_markTransferSpent(transferId);
_transferFromBridge(recipient, amount.sub(bonderFee));
if (bonderFee > 0) {
_transferFromBridge(msg.sender, bonderFee);
}
}
}
文件 3 的 8:IMessengerWrapper.sol
pragma solidity >=0.6.12 <0.8.0;
pragma experimental ABIEncoderV2;
interface IMessengerWrapper {
function sendCrossDomainMessage(bytes memory _calldata) external;
function verifySender(address l1BridgeCaller, bytes memory _data) external;
}
文件 4 的 8:L1_Bridge.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "./Bridge.sol";
import "../interfaces/IMessengerWrapper.sol";
abstract contract L1_Bridge is Bridge {
struct TransferBond {
address bonder;
uint256 createdAt;
uint256 totalAmount;
uint256 challengeStartTime;
address challenger;
bool challengeResolved;
}
mapping(uint256 => mapping(bytes32 => uint256)) public transferRootCommittedAt;
mapping(bytes32 => TransferBond) public transferBonds;
mapping(uint256 => mapping(address => uint256)) public timeSlotToAmountBonded;
mapping(uint256 => uint256) public chainBalance;
address public governance;
mapping(uint256 => IMessengerWrapper) public crossDomainMessengerWrappers;
mapping(uint256 => bool) public isChainIdPaused;
uint256 public challengePeriod = 1 days;
uint256 public challengeResolutionPeriod = 10 days;
uint256 public minTransferRootBondDelay = 15 minutes;
uint256 public constant CHALLENGE_AMOUNT_DIVISOR = 10;
uint256 public constant TIME_SLOT_SIZE = 4 hours;
event TransferSentToL2(
uint256 indexed chainId,
address indexed recipient,
uint256 amount,
uint256 amountOutMin,
uint256 deadline,
address indexed relayer,
uint256 relayerFee
);
event TransferRootBonded (
bytes32 indexed root,
uint256 amount
);
event TransferRootConfirmed(
uint256 indexed originChainId,
uint256 indexed destinationChainId,
bytes32 indexed rootHash,
uint256 totalAmount
);
event TransferBondChallenged(
bytes32 indexed transferRootId,
bytes32 indexed rootHash,
uint256 originalAmount
);
event ChallengeResolved(
bytes32 indexed transferRootId,
bytes32 indexed rootHash,
uint256 originalAmount
);
modifier onlyL2Bridge(uint256 chainId) {
IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId];
messengerWrapper.verifySender(msg.sender, msg.data);
_;
}
constructor (address[] memory bonders, address _governance) public Bridge(bonders) {
governance = _governance;
}
function sendToL2(
uint256 chainId,
address recipient,
uint256 amount,
uint256 amountOutMin,
uint256 deadline,
address relayer,
uint256 relayerFee
)
external
payable
{
IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId];
require(messengerWrapper != IMessengerWrapper(0), "L1_BRG: chainId not supported");
require(isChainIdPaused[chainId] == false, "L1_BRG: Sends to this chainId are paused");
require(amount > 0, "L1_BRG: Must transfer a non-zero amount");
require(amount >= relayerFee, "L1_BRG: Relayer fee cannot exceed amount");
_transferToBridge(msg.sender, amount);
bytes memory message = abi.encodeWithSignature(
"distribute(address,uint256,uint256,uint256,address,uint256)",
recipient,
amount,
amountOutMin,
deadline,
relayer,
relayerFee
);
chainBalance[chainId] = chainBalance[chainId].add(amount);
messengerWrapper.sendCrossDomainMessage(message);
emit TransferSentToL2(
chainId,
recipient,
amount,
amountOutMin,
deadline,
relayer,
relayerFee
);
}
function bondTransferRoot(
bytes32 rootHash,
uint256 destinationChainId,
uint256 totalAmount
)
external
onlyBonder
requirePositiveBalance
{
bytes32 transferRootId = getTransferRootId(rootHash, totalAmount);
require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot has already been confirmed");
require(transferBonds[transferRootId].createdAt == 0, "L1_BRG: TransferRoot has already been bonded");
uint256 currentTimeSlot = getTimeSlot(block.timestamp);
uint256 bondAmount = getBondForTransferAmount(totalAmount);
timeSlotToAmountBonded[currentTimeSlot][msg.sender] = timeSlotToAmountBonded[currentTimeSlot][msg.sender].add(bondAmount);
transferBonds[transferRootId] = TransferBond(
msg.sender,
block.timestamp,
totalAmount,
uint256(0),
address(0),
false
);
_distributeTransferRoot(rootHash, destinationChainId, totalAmount);
emit TransferRootBonded(rootHash, totalAmount);
}
function confirmTransferRoot(
uint256 originChainId,
bytes32 rootHash,
uint256 destinationChainId,
uint256 totalAmount,
uint256 rootCommittedAt
)
external
onlyL2Bridge(originChainId)
{
bytes32 transferRootId = getTransferRootId(rootHash, totalAmount);
require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot already confirmed");
require(rootCommittedAt > 0, "L1_BRG: rootCommittedAt must be greater than 0");
transferRootCommittedAt[destinationChainId][transferRootId] = rootCommittedAt;
chainBalance[originChainId] = chainBalance[originChainId].sub(totalAmount, "L1_BRG: Amount exceeds chainBalance. This indicates a layer-2 failure.");
TransferBond storage transferBond = transferBonds[transferRootId];
if (transferBond.createdAt == 0) {
_distributeTransferRoot(rootHash, destinationChainId, totalAmount);
}
emit TransferRootConfirmed(originChainId, destinationChainId, rootHash, totalAmount);
}
function _distributeTransferRoot(
bytes32 rootHash,
uint256 chainId,
uint256 totalAmount
)
internal
{
if (chainId == getChainId()) {
_setTransferRoot(rootHash, totalAmount);
} else {
chainBalance[chainId] = chainBalance[chainId].add(totalAmount);
IMessengerWrapper messengerWrapper = crossDomainMessengerWrappers[chainId];
require(messengerWrapper != IMessengerWrapper(0), "L1_BRG: chainId not supported");
bytes memory setTransferRootMessage = abi.encodeWithSignature(
"setTransferRoot(bytes32,uint256)",
rootHash,
totalAmount
);
messengerWrapper.sendCrossDomainMessage(setTransferRootMessage);
}
}
function challengeTransferBond(bytes32 rootHash, uint256 originalAmount, uint256 destinationChainId) external payable {
bytes32 transferRootId = getTransferRootId(rootHash, originalAmount);
TransferBond storage transferBond = transferBonds[transferRootId];
require(transferRootCommittedAt[destinationChainId][transferRootId] == 0, "L1_BRG: TransferRoot has already been confirmed");
require(transferBond.createdAt != 0, "L1_BRG: TransferRoot has not been bonded");
uint256 challengePeriodEnd = transferBond.createdAt.add(challengePeriod);
require(challengePeriodEnd >= block.timestamp, "L1_BRG: TransferRoot cannot be challenged after challenge period");
require(transferBond.challengeStartTime == 0, "L1_BRG: TransferRoot already challenged");
transferBond.challengeStartTime = block.timestamp;
transferBond.challenger = msg.sender;
uint256 timeSlot = getTimeSlot(transferBond.createdAt);
uint256 bondAmount = getBondForTransferAmount(originalAmount);
address bonder = transferBond.bonder;
timeSlotToAmountBonded[timeSlot][bonder] = timeSlotToAmountBonded[timeSlot][bonder].sub(bondAmount);
_addDebit(transferBond.bonder, bondAmount);
uint256 challengeStakeAmount = getChallengeAmountForTransferAmount(originalAmount);
_transferToBridge(msg.sender, challengeStakeAmount);
emit TransferBondChallenged(transferRootId, rootHash, originalAmount);
}
function resolveChallenge(bytes32 rootHash, uint256 originalAmount, uint256 destinationChainId) external {
bytes32 transferRootId = getTransferRootId(rootHash, originalAmount);
TransferBond storage transferBond = transferBonds[transferRootId];
require(transferBond.challengeStartTime != 0, "L1_BRG: TransferRoot has not been challenged");
require(block.timestamp > transferBond.challengeStartTime.add(challengeResolutionPeriod), "L1_BRG: Challenge period has not ended");
require(transferBond.challengeResolved == false, "L1_BRG: TransferRoot already resolved");
transferBond.challengeResolved = true;
uint256 challengeStakeAmount = getChallengeAmountForTransferAmount(originalAmount);
if (transferRootCommittedAt[destinationChainId][transferRootId] > 0) {
if (transferBond.createdAt > transferRootCommittedAt[destinationChainId][transferRootId].add(minTransferRootBondDelay)) {
_addCredit(transferBond.bonder, getBondForTransferAmount(originalAmount).add(challengeStakeAmount));
} else {
_addCredit(transferBond.challenger, challengeStakeAmount);
_addCredit(transferBond.bonder, getBondForTransferAmount(originalAmount));
}
} else {
_transferFromBridge(address(0xdead), challengeStakeAmount.mul(1).div(4));
_addCredit(transferBond.challenger, challengeStakeAmount.mul(7).div(4));
}
emit ChallengeResolved(transferRootId, rootHash, originalAmount);
}
function _additionalDebit(address bonder) internal view override returns (uint256) {
uint256 currentTimeSlot = getTimeSlot(block.timestamp);
uint256 bonded = 0;
uint256 numTimeSlots = challengePeriod / TIME_SLOT_SIZE;
for (uint256 i = 0; i < numTimeSlots; i++) {
bonded = bonded.add(timeSlotToAmountBonded[currentTimeSlot - i][bonder]);
}
return bonded;
}
function _requireIsGovernance() internal override {
require(governance == msg.sender, "L1_BRG: Caller is not the owner");
}
function setGovernance(address _newGovernance) external onlyGovernance {
require(_newGovernance != address(0), "L1_BRG: _newGovernance cannot be address(0)");
governance = _newGovernance;
}
function setCrossDomainMessengerWrapper(uint256 chainId, IMessengerWrapper _crossDomainMessengerWrapper) external onlyGovernance {
crossDomainMessengerWrappers[chainId] = _crossDomainMessengerWrapper;
}
function setChainIdDepositsPaused(uint256 chainId, bool isPaused) external onlyGovernance {
isChainIdPaused[chainId] = isPaused;
}
function setChallengePeriod(uint256 _challengePeriod) external onlyGovernance {
require(_challengePeriod % TIME_SLOT_SIZE == 0, "L1_BRG: challengePeriod must be divisible by TIME_SLOT_SIZE");
challengePeriod = _challengePeriod;
}
function setChallengeResolutionPeriod(uint256 _challengeResolutionPeriod) external onlyGovernance {
challengeResolutionPeriod = _challengeResolutionPeriod;
}
function setMinTransferRootBondDelay(uint256 _minTransferRootBondDelay) external onlyGovernance {
minTransferRootBondDelay = _minTransferRootBondDelay;
}
function getBondForTransferAmount(uint256 amount) public pure returns (uint256) {
return amount.add(getChallengeAmountForTransferAmount(amount));
}
function getChallengeAmountForTransferAmount(uint256 amount) public pure returns (uint256) {
return amount.div(CHALLENGE_AMOUNT_DIVISOR);
}
function getTimeSlot(uint256 time) public pure returns (uint256) {
return time / TIME_SLOT_SIZE;
}
}
文件 5 的 8:L1_ETH_Bridge.sol
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "./L1_Bridge.sol";
contract L1_ETH_Bridge is L1_Bridge {
constructor (address[] memory bonders, address _governance) public L1_Bridge(bonders, _governance) {}
function _transferFromBridge(address recipient, uint256 amount) internal override {
(bool success, ) = recipient.call{value: amount}(new bytes(0));
require(success, 'L1_ETH_BRG: ETH transfer failed');
}
function _transferToBridge(address , uint256 amount) internal override {
require(msg.value == amount, "L1_ETH_BRG: Value does not match amount");
}
}
文件 6 的 8:Lib_MerkleTree.sol
pragma solidity >0.5.0 <0.8.0;
library Lib_MerkleTree {
function getMerkleRoot(
bytes32[] memory _elements
)
internal
pure
returns (
bytes32
)
{
require(
_elements.length > 0,
"Lib_MerkleTree: Must provide at least one leaf hash."
);
if (_elements.length == 1) {
return _elements[0];
}
uint256[16] memory defaults = [
0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563,
0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d,
0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d,
0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8,
0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da,
0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5,
0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7,
0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead,
0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10,
0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82,
0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516,
0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c,
0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e,
0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab,
0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862,
0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10
];
bytes memory buf = new bytes(64);
bytes32 leftSibling;
bytes32 rightSibling;
uint256 rowSize = _elements.length;
uint256 depth = 0;
uint256 halfRowSize;
bool rowSizeIsOdd;
while (rowSize > 1) {
halfRowSize = rowSize / 2;
rowSizeIsOdd = rowSize % 2 == 1;
for (uint256 i = 0; i < halfRowSize; i++) {
leftSibling = _elements[(2 * i) ];
rightSibling = _elements[(2 * i) + 1];
assembly {
mstore(add(buf, 32), leftSibling )
mstore(add(buf, 64), rightSibling)
}
_elements[i] = keccak256(buf);
}
if (rowSizeIsOdd) {
leftSibling = _elements[rowSize - 1];
rightSibling = bytes32(defaults[depth]);
assembly {
mstore(add(buf, 32), leftSibling)
mstore(add(buf, 64), rightSibling)
}
_elements[halfRowSize] = keccak256(buf);
}
rowSize = halfRowSize + (rowSizeIsOdd ? 1 : 0);
depth++;
}
return _elements[0];
}
function verify(
bytes32 _root,
bytes32 _leaf,
uint256 _index,
bytes32[] memory _siblings,
uint256 _totalLeaves
)
internal
pure
returns (
bool
)
{
require(
_totalLeaves > 0,
"Lib_MerkleTree: Total leaves must be greater than zero."
);
require(
_index < _totalLeaves,
"Lib_MerkleTree: Index out of bounds."
);
require(
_siblings.length == _ceilLog2(_totalLeaves),
"Lib_MerkleTree: Total siblings does not correctly correspond to total leaves."
);
bytes32 computedRoot = _leaf;
for (uint256 i = 0; i < _siblings.length; i++) {
if ((_index & 1) == 1) {
computedRoot = keccak256(
abi.encodePacked(
_siblings[i],
computedRoot
)
);
} else {
computedRoot = keccak256(
abi.encodePacked(
computedRoot,
_siblings[i]
)
);
}
_index >>= 1;
}
return _root == computedRoot;
}
function _ceilLog2(
uint256 _in
)
private
pure
returns (
uint256
)
{
require(
_in > 0,
"Lib_MerkleTree: Cannot compute ceil(log_2) of 0."
);
if (_in == 1) {
return 0;
}
uint256 val = _in;
uint256 highest = 0;
for (uint256 i = 128; i >= 1; i >>= 1) {
if (val & (uint(1) << i) - 1 << i != 0) {
highest += i;
val >>= i;
}
}
if ((uint(1) << highest) != _in) {
highest += 1;
}
return highest;
}
}
文件 7 的 8:ReentrancyGuard.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 8 的 8:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
{
"compilationTarget": {
"contracts/bridges/L1_ETH_Bridge.sol": "L1_ETH_Bridge"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 50000
},
"remappings": []
}
[{"inputs":[{"internalType":"address[]","name":"bonders","type":"address[]"},{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newBonder","type":"address"}],"name":"BonderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousBonder","type":"address"}],"name":"BonderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferRootId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"originalAmount","type":"uint256"}],"name":"ChallengeResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bonder","type":"address"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalBondsSettled","type":"uint256"}],"name":"MultipleWithdrawalsSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferRootId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"originalAmount","type":"uint256"}],"name":"TransferBondChallenged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferRootBonded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"TransferRootConfirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"TransferRootSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"},{"indexed":true,"internalType":"address","name":"relayer","type":"address"},{"indexed":false,"internalType":"uint256","name":"relayerFee","type":"uint256"}],"name":"TransferSentToL2","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bonder","type":"address"},{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"rootHash","type":"bytes32"}],"name":"WithdrawalBondSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawalBonded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"transferNonce","type":"bytes32"}],"name":"Withdrew","type":"event"},{"inputs":[],"name":"CHALLENGE_AMOUNT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_SLOT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"addBonder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"bondTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"}],"name":"bondWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chainBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"challengeResolutionPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"name":"challengeTransferBond","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"rootCommittedAt","type":"uint256"}],"name":"confirmTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"crossDomainMessengerWrappers","outputs":[{"internalType":"contract IMessengerWrapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBondForTransferAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"}],"name":"getBondedWithdrawalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getChallengeAmountForTransferAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getDebitAndAdditionalDebit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"maybeBonder","type":"address"}],"name":"getIsBonder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"getRawDebit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"getTimeSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"getTransferId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"getTransferRoot","outputs":[{"components":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"amountWithdrawn","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct Bridge.TransferRoot","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"getTransferRootId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isChainIdPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transferId","type":"bytes32"}],"name":"isTransferIdSpent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTransferRootBondDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"}],"name":"removeBonder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueTransferRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"originalAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"name":"resolveChallenge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"relayer","type":"address"},{"internalType":"uint256","name":"relayerFee","type":"uint256"}],"name":"sendToL2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"isPaused","type":"bool"}],"name":"setChainIdDepositsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_challengePeriod","type":"uint256"}],"name":"setChallengePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_challengeResolutionPeriod","type":"uint256"}],"name":"setChallengeResolutionPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"contract IMessengerWrapper","name":"_crossDomainMessengerWrapper","type":"address"}],"name":"setCrossDomainMessengerWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernance","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minTransferRootBondDelay","type":"uint256"}],"name":"setMinTransferRootBondDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"transferRootTotalAmount","type":"uint256"},{"internalType":"uint256","name":"transferIdTreeIndex","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"},{"internalType":"uint256","name":"totalLeaves","type":"uint256"}],"name":"settleBondedWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"bytes32[]","name":"transferIds","type":"bytes32[]"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"settleBondedWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"timeSlotToAmountBonded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"transferBonds","outputs":[{"internalType":"address","name":"bonder","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"challengeStartTime","type":"uint256"},{"internalType":"address","name":"challenger","type":"address"},{"internalType":"bool","name":"challengeResolved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"transferRootCommittedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"transferNonce","type":"bytes32"},{"internalType":"uint256","name":"bonderFee","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"uint256","name":"transferRootTotalAmount","type":"uint256"},{"internalType":"uint256","name":"transferIdTreeIndex","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"},{"internalType":"uint256","name":"totalLeaves","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]