Skip to content

Commit

Permalink
all code ported, some failing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
proletesseract committed Nov 13, 2023
1 parent d0326eb commit 0061c76
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/interfaces/root/flowrate/IRootERC20BridgeFlowRate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,35 @@ interface IRootERC20BridgeFlowRateEvents {
uint256 refillRate,
uint256 largeTransferThreshold
);

/**
* @notice Indicates a withdrawal was queued.
* @param token Address of token that is being withdrawn.
* @param withdrawer Child chain sender of tokens.
* @param receiver Recipient of tokens.
* @param amount The number of tokens.
* @param delayWithdrawalLargeAmount is true if the reason for queuing was a large transfer.
* @param delayWithdrawalUnknownToken is true if the reason for queuing was that the
* token had not been configured using the setRateControlThreshold function.
* @param withdrawalQueueActivated is true if the withdrawal queue has been activated.
*/
event QueuedWithdrawal(
address indexed token,
address indexed withdrawer,
address indexed receiver,
uint256 amount,
bool delayWithdrawalLargeAmount,
bool delayWithdrawalUnknownToken,
bool withdrawalQueueActivated
);
}

interface IRootERC20BridgeFlowRateErrors {
// Error if the RootERC20Predicate initializer is called, and not the one for this contract.
error WrongInitializer();
// finaliseQueuedWithdrawalsAggregated was called with a zero length indices array.
error ProvideAtLeastOneIndex();
// The expected and actual token did not match for an aggregated withdrawal.
error MixedTokens(address token, address actualToken);
}

76 changes: 75 additions & 1 deletion src/root/flowrate/RootERC20BridgeFlowRate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,81 @@ contract RootERC20BridgeFlowRate is
revert NotMapped();
}
}
_executeTransfer(rootToken, childToken, withdrawer, receiver, amount);

// Update the flow rate checking. Delay the withdrawal if the request was
// for a token that has not been configured.
bool delayWithdrawalUnknownToken = _updateFlowRateBucket(rootToken, amount);
bool delayWithdrawalLargeAmount = false;

// Delay the withdrawal if the amount is greater than the threshold.
if (!delayWithdrawalUnknownToken) {
delayWithdrawalLargeAmount = (amount >= largeTransferThresholds[rootToken]);
}

// Ensure storage variable is cached on the stack.
bool queueActivated = withdrawalQueueActivated;

if (delayWithdrawalLargeAmount || delayWithdrawalUnknownToken || queueActivated) {
_enqueueWithdrawal(receiver, withdrawer, rootToken, amount);
emit QueuedWithdrawal(
rootToken,
withdrawer,
receiver,
amount,
delayWithdrawalLargeAmount,
delayWithdrawalUnknownToken,
queueActivated
);
} else {
_executeTransfer(rootToken, childToken, withdrawer, receiver, amount);
}
}

/**
* @notice Withdraw a queued withdrawal.
* @param receiver Address to withdraw value for.
* @param index Offset into array of queued withdrawals.
* @dev Only when not paused.
*/
function finaliseQueuedWithdrawal(address receiver, uint256 index) external nonReentrant {
(address withdrawer, address token, uint256 amount) = _processWithdrawal(receiver, index);
address childToken = rootTokenToChildToken[token];
_executeTransfer(token, childToken, withdrawer, receiver, amount);
}

/**
* @notice Withdraw one or more queued withdrawals for a specific token, aggregating the amounts.
* @param receiver Address to withdraw value for.
* @param token Token to do the aggregated withdrawal for.
* @param indices Offsets into array of queued withdrawals.
* @dev Only when not paused.
* Note that withdrawer in the ERC20Withdraw event emitted in the _executeTransfer function
* will represent the withdrawer of the last bridge transfer.
*/
function finaliseQueuedWithdrawalsAggregated(
address receiver,
address token,
uint256[] calldata indices
) external nonReentrant {
if (indices.length == 0) {
revert ProvideAtLeastOneIndex();
}
uint256 total = 0;
address withdrawer = address(0);
for (uint256 i = 0; i < indices.length; i++) {
address actualToken;
uint256 amount;
(withdrawer, actualToken, amount) = _processWithdrawal(receiver, indices[i]);
if (actualToken != token) {
revert MixedTokens(token, actualToken);
}
total += amount;
}
address childToken = rootTokenToChildToken[token];
_executeTransfer(token, childToken, withdrawer, receiver, total);
}

// slither-disable-next-line unused-state,naming-convention
uint256[50] private __gapRootERC20PredicateFlowRate;

}

0 comments on commit 0061c76

Please sign in to comment.