Skip to content
Merged
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
54 changes: 2 additions & 52 deletions contracts/HubPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,6 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable {
using SafeERC20 for IERC20;
using Address for address;

// A data worker can optimistically store several merkle roots on this contract by staking a bond and calling
// proposeRootBundle. By staking a bond, the data worker is alleging that the merkle roots all
// contain valid leaves that can be executed later to:
// - Send funds from this contract to a SpokePool or vice versa
// - Send funds from a SpokePool to Relayer as a refund for a relayed deposit
// - Send funds from a SpokePool to a deposit recipient to fulfill a "slow" relay
// Anyone can dispute this struct if the merkle roots contain invalid leaves before the
// requestExpirationTimestamp. Once the expiration timestamp is passed, executeRootBundle to execute a leaf
// from the poolRebalanceRoot on this contract and it will simultaneously publish the relayerRefundRoot and
// slowRelayRoot to a SpokePool. The latter two roots, once published to the SpokePool, contain
// leaves that can be executed on the SpokePool to pay relayers or recipients.
struct RootBundle {
// Contains leaves instructing this contract to send funds to SpokePools.
bytes32 poolRebalanceRoot;
// Relayer refund merkle root to be published to a SpokePool.
bytes32 relayerRefundRoot;
// Slow relay merkle root to be published to a SpokePool.
bytes32 slowRelayRoot;
// This is a 1D bitmap, with max size of 256 elements, limiting us to 256 chainsIds.
uint256 claimedBitMap;
// Proposer of this root bundle.
address proposer;
// Number of pool rebalance leaves to execute in the poolRebalanceRoot. After this number
// of leaves are executed, a new root bundle can be proposed
uint8 unclaimedPoolRebalanceLeafCount;
// When root bundle challenge period passes and this root bundle becomes executable.
uint32 requestExpirationTimestamp;
}

// Only one root bundle can be stored at a time. Once all pool rebalance leaves are executed, a new proposal
// can be submitted.
RootBundle public rootBundleProposal;
Expand All @@ -85,30 +56,9 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable {
// to 0x0 to disable a pool rebalance route and block executeRootBundle() from executing.
mapping(bytes32 => address) private poolRebalanceRoutes;

struct PooledToken {
// LP token given to LPs of a specific L1 token.
address lpToken;
// True if accepting new LP's.
bool isEnabled;
// Timestamp of last LP fee update.
uint32 lastLpFeeUpdate;
// Number of LP funds sent via pool rebalances to SpokePools and are expected to be sent
// back later.
int256 utilizedReserves;
// Number of LP funds held in contract less utilized reserves.
uint256 liquidReserves;
// Number of LP funds reserved to pay out to LPs as fees.
uint256 undistributedLpFees;
}

// Mapping of L1 token addresses to the associated pool information.
mapping(address => PooledToken) public pooledTokens;

// Helper contracts to facilitate cross chain actions between HubPool and SpokePool for a specific network.
struct CrossChainContract {
address adapter;
address spokePool;
}
// Mapping of chainId to the associated adapter and spokePool contracts.
mapping(uint256 => CrossChainContract) public crossChainContracts;

Expand Down Expand Up @@ -590,8 +540,8 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable {
* @param bundleEvaluationBlockNumbers should contain the latest block number for all chains, even if there are no
* relays contained on some of them. The usage of this variable should be defined in an off chain UMIP.
* @notice The caller of this function must approve this contract to spend bondAmount of bondToken.
* @param poolRebalanceLeafCount Number of leaves contained in pool rebalance root. Max is the number of whitelisted chains.
* @param poolRebalanceRoot Pool rebalance root containing leaves that will send tokens from this contract to a SpokePool.
* @param poolRebalanceLeafCount Number of leaves contained in pool rebalance root. Max is # of whitelisted chains.
* @param poolRebalanceRoot Pool rebalance root containing leaves that sends tokens from this contract to SpokePool.
* @param relayerRefundRoot Relayer refund root to publish to SpokePool where a data worker can execute leaves to
* refund relayers on their chosen refund chainId.
* @param slowRelayRoot Slow relay root to publish to Spoke Pool where a data worker can execute leaves to
Expand Down
59 changes: 56 additions & 3 deletions contracts/HubPoolInterface.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ interface HubPoolInterface {
// deposits in this bundle. If non-zero then it must be set on the SpokePool's RelayerRefundLeaf amountToReturn
// as -1 * this value to indicate if funds are being sent from or to the SpokePool.
int256[] netSendAmounts;
// This is only here to be emitted in an event to track a running unpaid balance between the L2 pool and the L1 pool.
// A positive number indicates that the HubPool owes the SpokePool funds. A negative number indicates that the
// SpokePool owes the HubPool funds. See the comment above for the dynamics of this and netSendAmounts
// This is only here to be emitted in an event to track a running unpaid balance between the L2 pool and the L1
// pool. A positive number indicates that the HubPool owes the SpokePool funds. A negative number indicates that
// the SpokePool owes the HubPool funds. See the comment above for the dynamics of this and netSendAmounts.
int256[] runningBalances;
// Used by data worker to mark which leaves should relay roots to SpokePools, and to otherwise organize leaves.
// For example, each leaf should contain all the rebalance information for a single chain, but in the case where
Expand All @@ -42,6 +42,59 @@ interface HubPoolInterface {
address[] l1Tokens;
}

// A data worker can optimistically store several merkle roots on this contract by staking a bond and calling
// proposeRootBundle. By staking a bond, the data worker is alleging that the merkle roots all contain valid leaves
// that can be executed later to:
// - Send funds from this contract to a SpokePool or vice versa
// - Send funds from a SpokePool to Relayer as a refund for a relayed deposit
// - Send funds from a SpokePool to a deposit recipient to fulfill a "slow" relay
// Anyone can dispute this struct if the merkle roots contain invalid leaves before the
// requestExpirationTimestamp. Once the expiration timestamp is passed, executeRootBundle to execute a leaf
// from the poolRebalanceRoot on this contract and it will simultaneously publish the relayerRefundRoot and
// slowRelayRoot to a SpokePool. The latter two roots, once published to the SpokePool, contain
// leaves that can be executed on the SpokePool to pay relayers or recipients.
struct RootBundle {
// Contains leaves instructing this contract to send funds to SpokePools.
bytes32 poolRebalanceRoot;
// Relayer refund merkle root to be published to a SpokePool.
bytes32 relayerRefundRoot;
// Slow relay merkle root to be published to a SpokePool.
bytes32 slowRelayRoot;
// This is a 1D bitmap, with max size of 256 elements, limiting us to 256 chainsIds.
uint256 claimedBitMap;
// Proposer of this root bundle.
address proposer;
// Number of pool rebalance leaves to execute in the poolRebalanceRoot. After this number
// of leaves are executed, a new root bundle can be proposed
uint8 unclaimedPoolRebalanceLeafCount;
// When root bundle challenge period passes and this root bundle becomes executable.
uint32 requestExpirationTimestamp;
}

// Each whitelisted L1 token has an associated pooledToken struct that contains all information used to track the
// cumulative LP positions and if this token is enabled for deposits.
struct PooledToken {
// LP token given to LPs of a specific L1 token.
address lpToken;
// True if accepting new LP's.
bool isEnabled;
// Timestamp of last LP fee update.
uint32 lastLpFeeUpdate;
// Number of LP funds sent via pool rebalances to SpokePools and are expected to be sent
// back later.
int256 utilizedReserves;
// Number of LP funds held in contract less utilized reserves.
uint256 liquidReserves;
// Number of LP funds reserved to pay out to LPs as fees.
uint256 undistributedLpFees;
}

// Helper contracts to facilitate cross chain actions between HubPool and SpokePool for a specific network.
struct CrossChainContract {
address adapter;
address spokePool;
}

function setPaused(bool pause) external;

function emergencyDeleteProposal() external;
Expand Down
12 changes: 0 additions & 12 deletions contracts/SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,6 @@ abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCall

mapping(address => mapping(uint256 => bool)) public enabledDepositRoutes;

// Stores collection of merkle roots that can be published to this contract from the HubPool, which are referenced
// by "data workers" via inclusion proofs to execute leaves in the roots.
struct RootBundle {
// Merkle root of slow relays that were not fully filled and whose recipient is still owed funds from the LP pool.
bytes32 slowRelayRoot;
// Merkle root of relayer refunds for successful relays.
bytes32 relayerRefundRoot;
// This is a 2D bitmap tracking which leaves in the relayer refund root have been claimed, with max size of
// 256x256 leaves per root.
mapping(uint256 => uint256) claimedBitmap;
}

// This contract can store as many root bundles as the HubPool chooses to publish here.
RootBundle[] public rootBundles;

Expand Down
12 changes: 12 additions & 0 deletions contracts/SpokePoolInterface.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ interface SpokePoolInterface {
uint32 depositId;
}

// Stores collection of merkle roots that can be published to this contract from the HubPool, which are referenced
// by "data workers" via inclusion proofs to execute leaves in the roots.
struct RootBundle {
// Merkle root of slow relays that were not fully filled and whose recipient is still owed funds from the LP pool.
bytes32 slowRelayRoot;
// Merkle root of relayer refunds for successful relays.
bytes32 relayerRefundRoot;
// This is a 2D bitmap tracking which leaves in the relayer refund root have been claimed, with max size of
// 256x256 leaves per root.
mapping(uint256 => uint256) claimedBitmap;
}

function setCrossDomainAdmin(address newCrossDomainAdmin) external;

function setHubPool(address newHubPool) external;
Expand Down