-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ctp): move Teleportr contracts to periphery (#2985)
Copies TeleportrDeposit and TeleportrDisburser to the contracts-periphery package in preparation for an upcoming audit. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
- Loading branch information
1 parent
0001b45
commit 019657d
Showing
13 changed files
with
720 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@eth-optimism/contracts-periphery': patch | ||
--- | ||
|
||
Add TeleportrDeposit and TeleportrDisburser to contracts-periphery |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
packages/contracts-periphery/contracts/L1/TeleportrDeposit.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.8.9; | ||
|
||
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
/** | ||
* @custom:attribution https://github.com/0xclem/teleportr | ||
* @title TeleportrDeposit | ||
* @notice A contract meant to manage deposits into Optimism's Teleportr custodial bridge. Deposits | ||
* are rate limited to avoid a situation where too much ETH is flowing through this bridge | ||
* and cannot be properly disbursed on L2. Inspired by 0xclem's original Teleportr system | ||
* (https://github.com/0xclem/teleportr). | ||
*/ | ||
contract TeleportrDeposit is Ownable { | ||
/** | ||
* @notice Minimum deposit amount (in wei). | ||
*/ | ||
uint256 public minDepositAmount; | ||
|
||
/** | ||
* @notice Maximum deposit amount (in wei). | ||
*/ | ||
uint256 public maxDepositAmount; | ||
|
||
/** | ||
* @notice Maximum balance this contract will hold before it starts rejecting deposits. | ||
*/ | ||
uint256 public maxBalance; | ||
|
||
/** | ||
* @notice Total number of deposits received. | ||
*/ | ||
uint256 public totalDeposits; | ||
|
||
/** | ||
* @notice Emitted any time the minimum deposit amount is set. | ||
* | ||
* @param previousAmount The previous minimum deposit amount. | ||
* @param newAmount The new minimum deposit amount. | ||
*/ | ||
event MinDepositAmountSet(uint256 previousAmount, uint256 newAmount); | ||
|
||
/** | ||
* @notice Emitted any time the maximum deposit amount is set. | ||
* | ||
* @param previousAmount The previous maximum deposit amount. | ||
* @param newAmount The new maximum deposit amount. | ||
*/ | ||
event MaxDepositAmountSet(uint256 previousAmount, uint256 newAmount); | ||
|
||
/** | ||
* @notice Emitted any time the contract maximum balance is set. | ||
* | ||
* @param previousBalance The previous maximum contract balance. | ||
* @param newBalance The new maximum contract balance. | ||
*/ | ||
event MaxBalanceSet(uint256 previousBalance, uint256 newBalance); | ||
|
||
/** | ||
* @notice Emitted any time the balance is withdrawn by the owner. | ||
* | ||
* @param owner The current owner and recipient of the funds. | ||
* @param balance The current contract balance paid to the owner. | ||
*/ | ||
event BalanceWithdrawn(address indexed owner, uint256 balance); | ||
|
||
/** | ||
* @notice Emitted any time a successful deposit is received. | ||
* | ||
* @param depositId A unique sequencer number identifying the deposit. | ||
* @param emitter The sending address of the payer. | ||
* @param amount The amount deposited by the payer. | ||
*/ | ||
event EtherReceived(uint256 indexed depositId, address indexed emitter, uint256 indexed amount); | ||
|
||
/** | ||
* @custom:semver 0.0.1 | ||
* | ||
* @param _minDepositAmount The initial minimum deposit amount. | ||
* @param _maxDepositAmount The initial maximum deposit amount. | ||
* @param _maxBalance The initial maximum contract balance. | ||
*/ | ||
constructor( | ||
uint256 _minDepositAmount, | ||
uint256 _maxDepositAmount, | ||
uint256 _maxBalance | ||
) { | ||
minDepositAmount = _minDepositAmount; | ||
maxDepositAmount = _maxDepositAmount; | ||
maxBalance = _maxBalance; | ||
totalDeposits = 0; | ||
emit MinDepositAmountSet(0, _minDepositAmount); | ||
emit MaxDepositAmountSet(0, _maxDepositAmount); | ||
emit MaxBalanceSet(0, _maxBalance); | ||
} | ||
|
||
/** | ||
* @notice Accepts deposits that will be disbursed to the sender's address on L2. | ||
*/ | ||
receive() external payable { | ||
require(msg.value >= minDepositAmount, "Deposit amount is too small"); | ||
require(msg.value <= maxDepositAmount, "Deposit amount is too big"); | ||
require(address(this).balance <= maxBalance, "Contract max balance exceeded"); | ||
|
||
emit EtherReceived(totalDeposits, msg.sender, msg.value); | ||
unchecked { | ||
totalDeposits += 1; | ||
} | ||
} | ||
|
||
/** | ||
* @notice Sends the contract's current balance to the owner. | ||
*/ | ||
function withdrawBalance() external onlyOwner { | ||
address _owner = owner(); | ||
uint256 _balance = address(this).balance; | ||
emit BalanceWithdrawn(_owner, _balance); | ||
payable(_owner).transfer(_balance); | ||
} | ||
|
||
/** | ||
* @notice Sets the minimum amount that can be deposited in a receive. | ||
* | ||
* @param _minDepositAmount The new minimum deposit amount. | ||
*/ | ||
function setMinAmount(uint256 _minDepositAmount) external onlyOwner { | ||
emit MinDepositAmountSet(minDepositAmount, _minDepositAmount); | ||
minDepositAmount = _minDepositAmount; | ||
} | ||
|
||
/** | ||
* @notice Sets the maximum amount that can be deposited in a receive. | ||
* | ||
* @param _maxDepositAmount The new maximum deposit amount. | ||
*/ | ||
function setMaxAmount(uint256 _maxDepositAmount) external onlyOwner { | ||
emit MaxDepositAmountSet(maxDepositAmount, _maxDepositAmount); | ||
maxDepositAmount = _maxDepositAmount; | ||
} | ||
|
||
/** | ||
* @notice Sets the maximum balance the contract can hold after a receive. | ||
* | ||
* @param _maxBalance The new maximum contract balance. | ||
*/ | ||
function setMaxBalance(uint256 _maxBalance) external onlyOwner { | ||
emit MaxBalanceSet(maxBalance, _maxBalance); | ||
maxBalance = _maxBalance; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
packages/contracts-periphery/contracts/L2/TeleportrDisburser.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.8.9; | ||
|
||
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | ||
|
||
/** | ||
* @title TeleportrDisburser | ||
*/ | ||
contract TeleportrDisburser is Ownable { | ||
/** | ||
* @notice A struct holding the address and amount to disbursement. | ||
*/ | ||
struct Disbursement { | ||
uint256 amount; | ||
address addr; | ||
} | ||
|
||
/** | ||
* @notice Total number of disbursements processed. | ||
*/ | ||
uint256 public totalDisbursements; | ||
|
||
/** | ||
* @notice Emitted any time the balance is withdrawn by the owner. | ||
* | ||
* @param owner The current owner and recipient of the funds. | ||
* @param balance The current contract balance paid to the owner. | ||
*/ | ||
event BalanceWithdrawn(address indexed owner, uint256 balance); | ||
|
||
/** | ||
* @notice Emitted any time a disbursement is successfuly sent. | ||
* | ||
* @param depositId The unique sequence number identifying the deposit. | ||
* @param to The recipient of the disbursement. | ||
* @param amount The amount sent to the recipient. | ||
*/ | ||
event DisbursementSuccess(uint256 indexed depositId, address indexed to, uint256 amount); | ||
|
||
/** | ||
* @notice Emitted any time a disbursement fails to send. | ||
* | ||
* @param depositId The unique sequence number identifying the deposit. | ||
* @param to The intended recipient of the disbursement. | ||
* @param amount The amount intended to be sent to the recipient. | ||
*/ | ||
event DisbursementFailed(uint256 indexed depositId, address indexed to, uint256 amount); | ||
|
||
/** | ||
* @custom:semver 0.0.1 | ||
*/ | ||
constructor() { | ||
totalDisbursements = 0; | ||
} | ||
|
||
/** | ||
* @notice Accepts a list of Disbursements and forwards the amount paid to the contract to each | ||
* recipient. Reverts if there are zero disbursements, the total amount to forward | ||
* differs from the amount sent in the transaction, or the _nextDepositId is | ||
* unexpected. Failed disbursements will not cause the method to revert, but will | ||
* instead be held by the contract and available for the owner to withdraw. | ||
* | ||
* @param _nextDepositId The depositId of the first Dispursement. | ||
* @param _disbursements A list of Disbursements to process. | ||
*/ | ||
function disburse(uint256 _nextDepositId, Disbursement[] calldata _disbursements) | ||
external | ||
payable | ||
onlyOwner | ||
{ | ||
// Ensure there are disbursements to process. | ||
uint256 _numDisbursements = _disbursements.length; | ||
require(_numDisbursements > 0, "No disbursements"); | ||
|
||
// Ensure the _nextDepositId matches our expected value. | ||
uint256 _depositId = totalDisbursements; | ||
require(_depositId == _nextDepositId, "Unexpected next deposit id"); | ||
unchecked { | ||
totalDisbursements += _numDisbursements; | ||
} | ||
|
||
// Ensure the amount sent in the transaction is equal to the sum of the | ||
// disbursements. | ||
uint256 _totalDisbursed = 0; | ||
for (uint256 i = 0; i < _numDisbursements; i++) { | ||
_totalDisbursed += _disbursements[i].amount; | ||
} | ||
require(_totalDisbursed == msg.value, "Disbursement total != amount sent"); | ||
|
||
// Process disbursements. | ||
for (uint256 i = 0; i < _numDisbursements; i++) { | ||
uint256 _amount = _disbursements[i].amount; | ||
address _addr = _disbursements[i].addr; | ||
|
||
// Deliver the dispursement amount to the receiver. If the | ||
// disbursement fails, the amount will be kept by the contract | ||
// rather than reverting to prevent blocking progress on other | ||
// disbursements. | ||
|
||
// slither-disable-next-line calls-loop,reentrancy-events | ||
(bool success, ) = _addr.call{ value: _amount, gas: 2300 }(""); | ||
if (success) emit DisbursementSuccess(_depositId, _addr, _amount); | ||
else emit DisbursementFailed(_depositId, _addr, _amount); | ||
|
||
unchecked { | ||
_depositId += 1; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @notice Sends the contract's current balance to the owner. | ||
*/ | ||
function withdrawBalance() external onlyOwner { | ||
address _owner = owner(); | ||
uint256 balance = address(this).balance; | ||
emit BalanceWithdrawn(_owner, balance); | ||
payable(_owner).transfer(balance); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
packages/contracts-periphery/contracts/testing/helpers/FailingReceiver.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.9; | ||
|
||
contract FailingReceiver { | ||
receive() external payable { | ||
require(false, "FailingReceiver"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.