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

fix(protocol): fix debitBond bug and add additional tests #18443

Merged
merged 4 commits into from
Nov 5, 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
15 changes: 9 additions & 6 deletions packages/protocol/contracts/layer1/based/LibBonds.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ library LibBonds {
event BondDebited(address indexed user, uint256 blockId, uint256 amount);

error L1_INVALID_MSG_VALUE();
error L1_ETH_NOT_PAID_AS_BOND();

/// @dev Deposits TAIKO tokens to be used as bonds.
/// @param _state Pointer to the protocol's storage.
Expand All @@ -48,7 +49,7 @@ library LibBonds {
public
{
_state.bondBalance[msg.sender] += _amount;
_handleDeposit(_resolver, _amount);
_handleDeposit(_resolver, msg.sender, _amount);
}

/// @dev Withdraws TAIKO tokens.
Expand Down Expand Up @@ -111,7 +112,8 @@ library LibBonds {
_state.bondBalance[_user] = balance - _amount;
}
} else {
_handleDeposit(_resolver, _amount);
// Note that the following function call will revert if bond asset is Ether.
_handleDeposit(_resolver, _user, _amount);
}
emit BondDebited(_user, _blockId, _amount);
}
Expand All @@ -138,17 +140,18 @@ library LibBonds {

/// @dev Handles the deposit of bond tokens or Ether.
/// @param _resolver The address resolver.
/// @param _user The user who made the deposit
/// @param _amount The amount of tokens or Ether to deposit.
function _handleDeposit(IAddressResolver _resolver, uint256 _amount) private {
function _handleDeposit(IAddressResolver _resolver, address _user, 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);
IERC20(bondToken).transferFrom(_user, address(this), _amount);
} else {
require(msg.value == _amount, L1_INVALID_MSG_VALUE());
require(msg.value == _amount, L1_ETH_NOT_PAID_AS_BOND());
}
emit BondDeposited(msg.sender, _amount);
emit BondDeposited(_user, _amount);
}

/// @dev Resolves the bond token address using the address resolver, returns address(0) if Ether
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ contract TokenUnlock is EssentialContract {
)
external
nonZeroAddr(_recipient)
nonZeroValue(uint256(_tgeTimestamp))
nonZeroValue(_tgeTimestamp)
initializer
{
if (_owner == _recipient) revert INVALID_PARAM();
Expand Down
69 changes: 69 additions & 0 deletions packages/protocol/test/layer1/based/TaikoL1TestGroup11.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./TaikoL1TestGroupBase.sol";

contract TaikoL10TestGroup11 is TaikoL1TestGroupBase {
// Test summary:
// 1. Zachary proposes a block with a custom proposer in the block parameters
// 2. The proposal will revert as Zachary is not registered as the preconf task manager.
function test_taikoL1_group_11_case_1() external {
vm.warp(1_000_000);
printBlockAndTrans(0);

giveEthAndTko(Zachary, 10_000 ether, 1000 ether);

ITierProvider(tr).getTier(LibTiers.TIER_OPTIMISTIC);

console2.log("====== Zachary proposes a block");

TaikoData.BlockParamsV2 memory params;
params.proposer = Alice;
proposeBlock(Zachary, params, LibProposing.L1_INVALID_CUSTOM_PROPOSER.selector);
}

// Test summary:
// 1. Zachary proposes a block with a Alice as the proposer
// 2. Alice proves the block
// 3. Alice verifies the block to get back her bonds.
function test_taikoL1_group_11_case_2() external {
registerAddress("preconf_task_manager", Zachary);

vm.warp(1_000_000);
printBlockAndTrans(0);

giveEthAndTko(Zachary, 10_000 ether, 1000 ether);
giveEthAndTko(Alice, 10_000 ether, 1000 ether);

ITierProvider.Tier memory tierOp = ITierProvider(tr).getTier(LibTiers.TIER_OPTIMISTIC);

console2.log("====== Zachary proposes a block with Alice as the proposer");

TaikoData.BlockParamsV2 memory params;
params.proposer = Alice;
TaikoData.BlockMetadataV2 memory meta = proposeBlock(Zachary, params, "");

assertEq(totalTkoBalance(tko, L1, Zachary), 10_000 ether);
assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - L1.getConfig().livenessBond);

console2.log("====== Alice proves the block");
// Prove the block
bytes32 blockHash = bytes32(uint256(10_000));
bytes32 stateRoot = bytes32(uint256(20_000));

mineAndWrap(10 seconds);
proveBlock(Alice, meta, GENESIS_BLOCK_HASH, blockHash, stateRoot, meta.minTier, "");

assertEq(totalTkoBalance(tko, L1, Zachary), 10_000 ether);
assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond);

printBlockAndTrans(meta.id);

console2.log("====== Alice's block is verified");
mineAndWrap(7 days);
verifyBlock(1);

assertEq(totalTkoBalance(tko, L1, Zachary), 10_000 ether);
assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether);
}
}
15 changes: 0 additions & 15 deletions packages/protocol/test/layer1/based/TaikoL1TestGroupBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,6 @@ abstract contract TaikoL1TestGroupBase is TaikoL1TestBase {
return L1.proposeBlockV2(abi.encode(params), new bytes(10));
}

function proposeBlockV2(
address proposer,
TaikoData.BlockParamsV2 memory params,
bytes4 revertReason
)
internal
returns (TaikoData.BlockMetadataV2 memory)
{
bytes memory txList = new bytes(10);

vm.prank(proposer);
if (revertReason != "") vm.expectRevert(revertReason);
return L1.proposeBlockV2(abi.encode(params), txList);
}

function proveBlock(
address prover,
TaikoData.BlockMetadataV2 memory meta,
Expand Down