Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(protocol): allow any ERC20 tokens or Ether to be used as bonds #18380

Merged
merged 10 commits into from
Nov 4, 2024
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
6 changes: 3 additions & 3 deletions packages/protocol/contracts/layer1/based/ITaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ interface ITaikoL1 {
/// @param _pause True to pause, false to unpause.
function pauseProving(bool _pause) external;

/// @notice Deposits Taiko token to be used as bonds.
/// @notice Deposits bond ERC20 token or Ether.
/// @param _amount The amount of Taiko token to deposit.
function depositBond(uint256 _amount) external;
function depositBond(uint256 _amount) external payable;

/// @notice Withdraws Taiko tokens.
/// @notice Withdraws bond ERC20 token or Ether.
/// @param _amount Amount of Taiko tokens to withdraw.
function withdrawBond(uint256 _amount) external;

Expand Down
59 changes: 41 additions & 18 deletions packages/protocol/contracts/layer1/based/LibBonds.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "src/shared/common/IAddressResolver.sol";
import "src/shared/common/LibAddress.sol";
import "src/shared/common/LibStrings.sol";
import "./TaikoData.sol";

Expand Down Expand Up @@ -33,9 +34,11 @@ library LibBonds {
/// @param amount The amount of tokens debited.
event BondDebited(address indexed user, uint256 blockId, uint256 amount);

error L1_INVALID_MSG_VALUE();

/// @dev Deposits TAIKO tokens to be used as bonds.
/// @param _state The current state of TaikoData.
/// @param _resolver The address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _resolver The address resolver.
/// @param _amount The amount of tokens to deposit.
function depositBond(
TaikoData.State storage _state,
Expand All @@ -44,14 +47,13 @@ library LibBonds {
)
public
{
emit BondDeposited(msg.sender, _amount);
_state.bondBalance[msg.sender] += _amount;
_tko(_resolver).transferFrom(msg.sender, address(this), _amount);
_handleDeposit(_resolver, _amount);
}

/// @dev Withdraws TAIKO tokens.
/// @param _state The current state of TaikoData.
/// @param _resolver The address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _resolver The address resolver.
/// @param _amount The amount of tokens to withdraw.
function withdrawBond(
TaikoData.State storage _state,
Expand All @@ -62,11 +64,17 @@ library LibBonds {
{
emit BondWithdrawn(msg.sender, _amount);
_state.bondBalance[msg.sender] -= _amount;
_tko(_resolver).transfer(msg.sender, _amount);

address bondToken = _bondToken(_resolver);
if (bondToken != address(0)) {
IERC20(bondToken).transfer(msg.sender, _amount);
} else {
LibAddress.sendEtherAndVerify(msg.sender, _amount);
}
}

/// @dev Gets a user's current TAIKO token bond balance.
/// @param _state The current state of TaikoData.
/// @param _state Pointer to the protocol's storage.
/// @param _user The address of the user.
/// @return The current token balance.
function bondBalanceOf(
Expand All @@ -81,8 +89,8 @@ library LibBonds {
}

/// @dev Debits TAIKO tokens as bonds.
/// @param _state The current state of TaikoData.
/// @param _resolver The address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _resolver The address resolver.
/// @param _user The address of the user to debit.
/// @param _blockId The ID of the block to debit for.
/// @param _amount The amount of tokens to debit.
Expand All @@ -103,14 +111,13 @@ library LibBonds {
_state.bondBalance[_user] = balance - _amount;
}
} else {
emit BondDeposited(msg.sender, _amount);
_tko(_resolver).transferFrom(_user, address(this), _amount);
_handleDeposit(_resolver, _amount);
}
emit BondDebited(_user, _blockId, _amount);
}

/// @dev Credits TAIKO tokens to a user's bond balance.
/// @param _state The current state of TaikoData.
/// @param _state Pointer to the protocol's storage.
/// @param _user The address of the user to credit.
/// @param _blockId The ID of the block to credit for.
/// @param _amount The amount of tokens to credit.
Expand All @@ -129,10 +136,26 @@ library LibBonds {
emit BondCredited(_user, _blockId, _amount);
}

/// @dev Resolves the TAIKO token address using the address resolver.
/// @param _resolver The address resolver interface.
/// @return tko_ The IERC20 interface of the TAIKO token.
function _tko(IAddressResolver _resolver) private view returns (IERC20) {
return IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false));
/// @dev Handles the deposit of bond tokens or Ether.
/// @param _resolver The address resolver.
/// @param _amount The amount of tokens or Ether to deposit.
function _handleDeposit(IAddressResolver _resolver, uint256 _amount) private {
address bondToken = _bondToken(_resolver);

if (bondToken != address(0)) {
require(msg.value == 0, L1_INVALID_MSG_VALUE());
IERC20(bondToken).transferFrom(msg.sender, address(this), _amount);
} else {
require(msg.value == _amount, L1_INVALID_MSG_VALUE());
}
emit BondDeposited(msg.sender, _amount);
}

/// @dev Resolves the bond token address using the address resolver, returns address(0) if Ether
/// is used as bond asset.
/// @param _resolver The address resolver.
/// @return The IERC20 interface of the TAIKO token.
function _bondToken(IAddressResolver _resolver) private view returns (address) {
return _resolver.resolve(LibStrings.B_BOND_TOKEN, true);
}
}
12 changes: 6 additions & 6 deletions packages/protocol/contracts/layer1/based/LibProposing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ library LibProposing {
error L1_UNEXPECTED_PARENT();

/// @dev Proposes multiple Taiko L2 blocks.
/// @param _state The current state of the Taiko protocol.
/// @param _state Pointer to the protocol's storage.
/// @param _config The configuration parameters for the Taiko protocol.
/// @param _resolver The address resolver interface.
/// @param _resolver The address resolver.
/// @param _paramsArr An array of encoded data bytes containing the block parameters.
/// @param _txListArr An array of transaction list bytes (if not blob).
/// @return metas_ An array of metadata objects for the proposed L2 blocks (version 2).
Expand Down Expand Up @@ -82,9 +82,9 @@ library LibProposing {
}

/// @dev Proposes a single Taiko L2 block.
/// @param _state The current state of the Taiko protocol.
/// @param _state Pointer to the protocol's storage.
/// @param _config The configuration parameters for the Taiko protocol.
/// @param _resolver The address resolver interface.
/// @param _resolver The address resolver.
/// @param _params Encoded data bytes containing the block parameters.
/// @param _txList Transaction list bytes (if not blob).
/// @return meta_ The metadata of the proposed block (version 2).
Expand All @@ -108,9 +108,9 @@ library LibProposing {
}

/// @dev Proposes a single Taiko L2 block.
/// @param _state The current state of the Taiko protocol.
/// @param _state Pointer to the protocol's storage.
/// @param _config The configuration parameters for the Taiko protocol.
/// @param _resolver The address resolver interface.
/// @param _resolver The address resolver.
/// @param _params Encoded data bytes containing the block parameters.
/// @param _txList Transaction list bytes (if not blob).
/// @return meta_ The metadata of the proposed block (version 2).
Expand Down
26 changes: 13 additions & 13 deletions packages/protocol/contracts/layer1/based/LibProving.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ library LibProving {
error L1_PROVING_PAUSED();

/// @dev Pauses or unpauses the proving process.
/// @param _state Current TaikoData.State.
/// @param _state Pointer to the protocol's storage.
/// @param _pause The pause status.
function pauseProving(TaikoData.State storage _state, bool _pause) public {
require(_state.slotB.provingPaused != _pause, L1_INVALID_PAUSE_STATUS());
Expand All @@ -93,9 +93,9 @@ library LibProving {
}

/// @dev Proves or contests multiple Taiko L2 blocks.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _resolver Address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _resolver The address resolver.
/// @param _blockIds The index of the block to prove. This is also used to select the right
/// implementation version.
/// @param _inputs A list of abi-encoded (TaikoData.BlockMetadataV2, TaikoData.Transition,
Expand Down Expand Up @@ -152,9 +152,9 @@ library LibProving {
}

/// @dev Proves or contests a single Taiko L2 block.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _resolver Address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _resolver The address resolver.
/// @param _blockId The index of the block to prove. This is also used to select the right
/// implementation version.
/// @param _input An abi-encoded (TaikoData.BlockMetadataV2, TaikoData.Transition,
Expand All @@ -173,9 +173,9 @@ library LibProving {
}

/// @dev Proves or contests a single Taiko L2 block.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _resolver Address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _resolver The address resolver.
/// @param _blockId The index of the block to prove. This is also used to select the right
/// implementation version.
/// @param _input An abi-encoded (TaikoData.BlockMetadataV2, TaikoData.Transition,
Expand Down Expand Up @@ -393,7 +393,7 @@ library LibProving {
}

/// @dev Handle the transition initialization logic.
/// @param _state Current TaikoData.State.
/// @param _state Pointer to the protocol's storage.
/// @param _blk Current TaikoData.BlockV2.
/// @param _tran Current TaikoData.Transition.
/// @param _local Current Local struct.
Expand Down Expand Up @@ -459,8 +459,8 @@ library LibProving {

/// @dev Handles what happens when either the first transition is being proven or there is a
/// higher tier proof incoming.
/// @param _state Current TaikoData.State.
/// @param _resolver Address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _resolver The address resolver.
/// @param _blk Current TaikoData.BlockV2.
/// @param _ts Current TaikoData.TransitionState.
/// @param _tran Current TaikoData.Transition.
Expand Down
24 changes: 11 additions & 13 deletions packages/protocol/contracts/layer1/based/LibUtils.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "src/shared/common/IAddressResolver.sol";
import "src/shared/common/LibStrings.sol";
import "src/shared/common/LibMath.sol";
Expand Down Expand Up @@ -66,8 +64,8 @@ library LibUtils {
}

/// @dev Retrieves a block's block hash and state root.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockId Id of the block.
/// @return blockHash_ The block's block hash.
/// @return stateRoot_ The block's storage root.
Expand Down Expand Up @@ -95,8 +93,8 @@ library LibUtils {

/// @dev Gets the state transitions for a batch of block. For transition that doesn't exist, the
/// corresponding transition state will be empty.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockIds Id array of the blocks.
/// @param _parentHashes Parent hashes of the blocks.
/// @return transitions_ The state transition pointer array.
Expand Down Expand Up @@ -124,8 +122,8 @@ library LibUtils {

/// @dev Retrieves the transition with a given parentHash.
/// @dev This function will revert if the transition is not found.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockId Id of the block.
/// @param _parentHash Parent hash of the block.
/// @return The state transition pointer.
Expand All @@ -148,8 +146,8 @@ library LibUtils {
}

/// @dev Retrieves a block based on its ID.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockId Id of the block.
/// @return blk_ The block storage pointer.
/// @return slot_ The slot value.
Expand All @@ -169,8 +167,8 @@ library LibUtils {

/// @dev Retrieves the transition with a transition ID.
/// @dev This function will revert if the transition is not found.
/// @param _state Current TaikoData.State.
/// @param _config Actual TaikoData.Config.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockId Id of the block.
/// @param _tid The transition id.
/// @return The state transition pointer.
Expand All @@ -193,7 +191,7 @@ library LibUtils {

/// @dev Retrieves the ID of the transition with a given parentHash. This function will return 0
/// if the transition is not found.
/// @param _state Current TaikoData.State.
/// @param _state Pointer to the protocol's storage.
/// @param _blk The block storage pointer.
/// @param _slot The slot value.
/// @param _parentHash The parent hash of the block.
Expand Down
10 changes: 5 additions & 5 deletions packages/protocol/contracts/layer1/based/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ library LibVerifying {
error L1_TRANSITION_ID_ZERO();

/// @dev Verifies up to N blocks.
/// @param _state The current state of TaikoData.
/// @param _config The configuration of TaikoData.
/// @param _resolver The address resolver interface.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _resolver The address resolver.
/// @param _maxBlocksToVerify The maximum number of blocks to verify.
function verifyBlocks(
TaikoData.State storage _state,
Expand Down Expand Up @@ -175,8 +175,8 @@ library LibVerifying {
}

/// @dev Retrieves the prover of a verified block.
/// @param _state The current state of TaikoData.
/// @param _config The configuration of TaikoData.
/// @param _state Pointer to the protocol's storage.
/// @param _config The protocol's configuration.
/// @param _blockId The ID of the block.
/// @return The address of the prover.
function getVerifiedBlockProver(
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/contracts/layer1/based/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents {
}

/// @inheritdoc ITaikoL1
function depositBond(uint256 _amount) external whenNotPaused {
function depositBond(uint256 _amount) external payable whenNotPaused {
LibBonds.depositBond(state, this, _amount);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ contract RollupAddressCache is AddressCache {
return (false, address(0));
}

if (_name == LibStrings.B_BOND_TOKEN) {
return (true, 0x10dea67478c5F8C5E2D90e5E9B26dBe60c54d800);
}
if (_name == LibStrings.B_TAIKO_TOKEN) {
return (true, 0x10dea67478c5F8C5E2D90e5E9B26dBe60c54d800);
}
Expand Down
Loading