From e505392068084faa37b4b0d138ac79012256c692 Mon Sep 17 00:00:00 2001 From: Daniel Wang <99078276+dantaik@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:33:55 +0800 Subject: [PATCH] feat(protocol): allow TAIKO token bonds deposits and withdrawal (#17725) --- packages/protocol/contracts/L1/ITaikoL1.sol | 8 ++ packages/protocol/contracts/L1/TaikoData.sol | 3 +- .../protocol/contracts/L1/TaikoEvents.sol | 6 ++ packages/protocol/contracts/L1/TaikoL1.sol | 47 ++++---- .../protocol/contracts/L1/libs/LibBonds.sol | 102 ++++++++++++++++++ .../contracts/L1/libs/LibProposing.sol | 5 +- .../protocol/contracts/L1/libs/LibProving.sol | 23 ++-- .../protocol/contracts/L1/libs/LibUtils.sol | 1 - .../contracts/L1/libs/LibVerifying.sol | 17 +-- .../contracts/team/proving/ProverSet.sol | 10 ++ .../protocol/test/L1/TaikoL1TestGroup1.t.sol | 32 +++--- .../protocol/test/L1/TaikoL1TestGroup10.t.sol | 2 +- .../protocol/test/L1/TaikoL1TestGroup2.t.sol | 31 +++--- .../protocol/test/L1/TaikoL1TestGroup3.t.sol | 39 +++---- .../protocol/test/L1/TaikoL1TestGroup4.t.sol | 8 +- .../protocol/test/L1/TaikoL1TestGroup5.t.sol | 32 +++--- .../protocol/test/L1/TaikoL1TestGroup6.t.sol | 8 +- .../protocol/test/L1/TaikoL1TestGroup9.t.sol | 36 +++---- .../protocol/test/L1/TaikoL1TestGroupBase.sol | 12 +++ 19 files changed, 279 insertions(+), 143 deletions(-) create mode 100644 packages/protocol/contracts/L1/libs/LibBonds.sol diff --git a/packages/protocol/contracts/L1/ITaikoL1.sol b/packages/protocol/contracts/L1/ITaikoL1.sol index b758d4a710..b4bec95896 100644 --- a/packages/protocol/contracts/L1/ITaikoL1.sol +++ b/packages/protocol/contracts/L1/ITaikoL1.sol @@ -34,6 +34,14 @@ interface ITaikoL1 { /// @param _pause True if paused. function pauseProving(bool _pause) external; + /// @notice Deposits Taiko token to be used as bonds. + /// @param _amount The amount of Taiko token to deposit. + function depositBond(uint256 _amount) external; + + /// @notice Withdraws Taiko token. + /// @param _amount The amount of Taiko token to withdraw. + function withdrawBond(uint256 _amount) external; + /// @notice Gets the configuration of the TaikoL1 contract. /// @return Config struct containing configuration parameters. function getConfig() external pure returns (TaikoData.Config memory); diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index b4a872651f..c657d3f8f3 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -172,6 +172,7 @@ library TaikoData { bytes32 __reserve1; SlotA slotA; // slot 5 SlotB slotB; // slot 6 - uint256[44] __gap; + mapping(address account => uint256 bond) bondBalance; + uint256[43] __gap; } } diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 4259ae8361..5801111a4c 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -11,6 +11,12 @@ import "./TaikoData.sol"; /// L1 libraries. /// @custom:security-contact security@taiko.xyz abstract contract TaikoEvents { + /// @dev Emitted when token is credited back to a user's bond balance. + event BondCredited(address indexed user, uint256 amount); + + /// @dev Emitted when token is debited from a user's bond balance. + event BondDebited(address indexed user, uint256 amount); + /// @dev Emitted when a block is proposed. /// @param blockId The ID of the proposed block. /// @param assignedProver The block's assigned prover. diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 6216f70dd1..3a28c9fc2c 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -79,12 +79,11 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { returns (TaikoData.BlockMetadata memory meta_, TaikoData.EthDeposit[] memory deposits_) { TaikoData.Config memory config = getConfig(); - TaikoToken tko = TaikoToken(resolve(LibStrings.B_TAIKO_TOKEN, false)); - (meta_, deposits_) = LibProposing.proposeBlock(state, tko, config, this, _params, _txList); + (meta_, deposits_) = LibProposing.proposeBlock(state, config, this, _params, _txList); if (LibUtils.shouldVerifyBlocks(config, meta_.id, true) && !state.slotB.provingPaused) { - LibVerifying.verifyBlocks(state, tko, config, this, config.maxBlocksToVerify); + LibVerifying.verifyBlocks(state, config, this, config.maxBlocksToVerify); } } @@ -100,12 +99,10 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { emitEventForClient { TaikoData.Config memory config = getConfig(); - TaikoToken tko = TaikoToken(resolve(LibStrings.B_TAIKO_TOKEN, false)); - - LibProving.proveBlock(state, tko, config, this, _blockId, _input); + LibProving.proveBlock(state, config, this, _blockId, _input); if (LibUtils.shouldVerifyBlocks(config, _blockId, false)) { - LibVerifying.verifyBlocks(state, tko, config, this, config.maxBlocksToVerify); + LibVerifying.verifyBlocks(state, config, this, config.maxBlocksToVerify); } } @@ -117,13 +114,29 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { nonReentrant emitEventForClient { - LibVerifying.verifyBlocks( - state, - TaikoToken(resolve(LibStrings.B_TAIKO_TOKEN, false)), - getConfig(), - this, - _maxBlocksToVerify - ); + LibVerifying.verifyBlocks(state, getConfig(), this, _maxBlocksToVerify); + } + + /// @inheritdoc ITaikoL1 + function pauseProving(bool _pause) external { + _authorizePause(msg.sender, _pause); + LibProving.pauseProving(state, _pause); + } + + /// @inheritdoc ITaikoL1 + function depositBond(uint256 _amount) external whenNotPaused { + LibBonds.depositBond(state, this, _amount); + } + + /// @inheritdoc ITaikoL1 + function withdrawBond(uint256 _amount) external whenNotPaused { + LibBonds.withdrawBond(state, this, _amount); + } + + /// @notice Gets the current bond balance of a given address. + /// @return The current bond balance. + function bondBalanceOf(address _user) external view returns (uint256) { + return LibBonds.bondBalanceOf(state, _user); } /// @notice Gets the details of a block. @@ -201,12 +214,6 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { return (state.slotA, state.slotB); } - /// @inheritdoc ITaikoL1 - function pauseProving(bool _pause) external { - _authorizePause(msg.sender, _pause); - LibProving.pauseProving(state, _pause); - } - /// @inheritdoc EssentialContract function unpause() public override { super.unpause(); // permission checked inside diff --git a/packages/protocol/contracts/L1/libs/LibBonds.sol b/packages/protocol/contracts/L1/libs/LibBonds.sol new file mode 100644 index 0000000000..83796aa2cd --- /dev/null +++ b/packages/protocol/contracts/L1/libs/LibBonds.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import "../../common/IAddressResolver.sol"; +import "../../common/LibStrings.sol"; +import "../TaikoData.sol"; + +/// @title LibBonds +/// @notice A library that offers helper functions to handle bonds. +/// @custom:security-contact security@taiko.xyz +library LibBonds { + /// @dev Emitted when token is credited back to a user's bond balance. + event BondCredited(address indexed user, uint256 amount); + + /// @dev Emitted when token is debited from a user's bond balance. + event BondDebited(address indexed user, uint256 amount); + + /// @dev Deposits Taiko token to be used as bonds. + /// @param _state Current TaikoData.State. + /// @param _resolver Address resolver interface. + /// @param _amount The amount of token to deposit. + function depositBond( + TaikoData.State storage _state, + IAddressResolver _resolver, + uint256 _amount + ) + internal + { + _state.bondBalance[msg.sender] += _amount; + _tko(_resolver).transferFrom(msg.sender, address(this), _amount); + } + + /// @dev Withdraws Taiko token. + /// @param _state Current TaikoData.State. + /// @param _resolver Address resolver interface. + /// @param _amount The amount of token to withdraw. + function withdrawBond( + TaikoData.State storage _state, + IAddressResolver _resolver, + uint256 _amount + ) + internal + { + _state.bondBalance[msg.sender] -= _amount; + _tko(_resolver).transfer(msg.sender, _amount); + } + + /// @dev Debits Taiko tokens as bonds. + /// @param _state Current TaikoData.State. + /// @param _resolver Address resolver interface. + /// @param _user The user address to debit. + /// @param _amount The amount of token to debit. + function debitBond( + TaikoData.State storage _state, + IAddressResolver _resolver, + address _user, + uint256 _amount + ) + internal + { + uint256 balance = _state.bondBalance[_user]; + + if (balance >= _amount) { + unchecked { + _state.bondBalance[_user] = balance - _amount; + } + emit BondDebited(_user, _amount); + } else { + _tko(_resolver).transferFrom(_user, address(this), _amount); + } + } + + /// @dev Credits Taiko tokens to user's bond balance. + /// @param _state Current TaikoData.State. + /// @param _user The user address to credit. + /// @param _amount The amount of token to credit. + function creditBond(TaikoData.State storage _state, address _user, uint256 _amount) internal { + _state.bondBalance[_user] += _amount; + emit BondCredited(_user, _amount); + } + + /// @dev Gets a user's current Taiko token bond balance. + /// @param _state Current TaikoData.State. + /// @param _user The user address to credit. + /// @return The current token balance. + function bondBalanceOf( + TaikoData.State storage _state, + address _user + ) + internal + view + returns (uint256) + { + return _state.bondBalance[_user]; + } + + function _tko(IAddressResolver _resolver) private view returns (IERC20) { + return IERC20(_resolver.resolve(LibStrings.B_TAIKO_TOKEN, false)); + } +} diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 320e792fc2..56137845a3 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../../libs/LibAddress.sol"; import "../../libs/LibNetwork.sol"; +import "./LibBonds.sol"; import "./LibUtils.sol"; /// @title LibProposing @@ -53,7 +54,6 @@ library LibProposing { /// @dev Proposes a Taiko L2 block. /// @param _state Current TaikoData.State. - /// @param _tko The taiko token. /// @param _config Actual TaikoData.Config. /// @param _resolver Address resolver interface. /// @param _data Encoded data bytes containing the block params. @@ -61,7 +61,6 @@ library LibProposing { /// @return meta_ The constructed block's metadata. function proposeBlock( TaikoData.State storage _state, - TaikoToken _tko, TaikoData.Config memory _config, IAddressResolver _resolver, bytes calldata _data, @@ -188,7 +187,7 @@ library LibProposing { ++_state.slotB.numBlocks; } - _tko.transferFrom(msg.sender, address(this), _config.livenessBond); + LibBonds.debitBond(_state, _resolver, msg.sender, _config.livenessBond); // Bribe the block builder. Unlock 1559-tips, this tip is only made // if this transaction succeeds. diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index ebc13cf31d..3072e99f8a 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import "../../verifiers/IVerifier.sol"; +import "./LibBonds.sol"; import "./LibUtils.sol"; /// @title LibProving @@ -16,7 +17,6 @@ library LibProving { TaikoData.SlotB b; ITierProvider.Tier tier; ITierProvider.Tier minTier; - TaikoToken tko; bytes32 metaHash; address assignedProver; bytes32 stateRoot; @@ -89,7 +89,6 @@ library LibProving { /// @dev Proves or contests a block transition. /// @param _state Current TaikoData.State. - /// @param _tko The taiko token. /// @param _config Actual TaikoData.Config. /// @param _resolver Address resolver interface. /// @param _blockId The index of the block to prove. This is also used to @@ -98,7 +97,6 @@ library LibProving { /// TaikoData.TierProof) tuple. function proveBlock( TaikoData.State storage _state, - TaikoToken _tko, TaikoData.Config memory _config, IAddressResolver _resolver, uint64 _blockId, @@ -122,7 +120,6 @@ library LibProving { } Local memory local; - local.tko = _tko; local.b = _state.slotB; // Check that the block has been proposed but has not yet been verified. @@ -232,7 +229,7 @@ library LibProving { // Handles the case when an incoming tier is higher than the current transition's tier. // Reverts when the incoming proof tries to prove the same transition // (L1_ALREADY_PROVED). - _overrideWithHigherProof(blk, ts, tran, proof, local); + _overrideWithHigherProof(_state, _resolver, blk, ts, tran, proof, local); emit TransitionProved({ blockId: local.blockId, @@ -278,7 +275,7 @@ library LibProving { // _checkIfContestable(/*_state,*/ tier.cooldownWindow, ts.timestamp); // Burn the contest bond from the prover. - _tko.transferFrom(msg.sender, address(this), local.tier.contestBond); + LibBonds.debitBond(_state, _resolver, msg.sender, local.tier.contestBond); // We retain the contest bond within the transition, just in // case this configuration is altered to a different value @@ -383,6 +380,8 @@ library LibProving { // validity bond `V` ratio is `C/V = 21/(32*r)`, and if `r` set at 10%, the C/V ratio will be // 6.5625. function _overrideWithHigherProof( + TaikoData.State storage _state, + IAddressResolver _resolver, TaikoData.Block storage _blk, TaikoData.TransitionState memory _ts, TaikoData.Transition memory _tran, @@ -400,13 +399,13 @@ library LibProving { reward = _rewardAfterFriction(_ts.contestBond); // We return the validity bond back, but the original prover doesn't get any reward. - _local.tko.transfer(_ts.prover, _ts.validityBond); + LibBonds.creditBond(_state, _ts.prover, _ts.validityBond); } else { // The contested transition is proven to be invalid, contester wins the game. // Contester gets 3/4 of reward, the new prover gets 1/4. reward = _rewardAfterFriction(_ts.validityBond) >> 2; - _local.tko.transfer(_ts.contester, _ts.contestBond + reward * 3); + LibBonds.creditBond(_state, _ts.contester, _ts.contestBond + reward * 3); } } else { if (_local.sameTransition) revert L1_ALREADY_PROVED(); @@ -425,7 +424,7 @@ library LibProving { if (_local.assignedProver == msg.sender) { reward += _local.livenessBond; } else { - _local.tko.transfer(_local.assignedProver, _local.livenessBond); + LibBonds.creditBond(_state, _local.assignedProver, _local.livenessBond); } } } @@ -433,11 +432,9 @@ library LibProving { unchecked { if (reward > _local.tier.validityBond) { - _local.tko.transfer(msg.sender, reward - _local.tier.validityBond); + LibBonds.creditBond(_state, msg.sender, reward - _local.tier.validityBond); } else if (reward < _local.tier.validityBond) { - _local.tko.transferFrom( - msg.sender, address(this), _local.tier.validityBond - reward - ); + LibBonds.debitBond(_state, _resolver, msg.sender, _local.tier.validityBond - reward); } } diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index cb66f7d4a2..fe0de80b4f 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -5,7 +5,6 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../common/IAddressResolver.sol"; import "../../common/LibStrings.sol"; -import "../../tko/TaikoToken.sol"; import "../../libs/LibMath.sol"; import "../tiers/ITierProvider.sol"; import "../tiers/ITierRouter.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index a507eee05e..5e2c11e449 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import "../../signal/ISignalService.sol"; import "./LibUtils.sol"; +import "./LibBonds.sol"; /// @title LibVerifying /// @notice A library for handling block verification in the Taiko protocol. @@ -27,7 +28,6 @@ library LibVerifying { } // Warning: Any errors defined here must also be defined in TaikoErrors.sol. - error L1_BATCH_TRANSFER_FAILED(); error L1_BLOCK_MISMATCH(); error L1_INVALID_CONFIG(); error L1_TRANSITION_ID_ZERO(); @@ -36,7 +36,6 @@ library LibVerifying { /// @dev Verifies up to N blocks. function verifyBlocks( TaikoData.State storage _state, - TaikoToken _tko, TaikoData.Config memory _config, IAddressResolver _resolver, uint64 _maxBlocksToVerify @@ -71,9 +70,6 @@ library LibVerifying { // - blockId and numBlocksVerified values incremented will still be OK in the // next 584K years if we verifying one block per every second - address[] memory provers = new address[](_maxBlocksToVerify); - uint256[] memory bonds = new uint256[](_maxBlocksToVerify); - unchecked { ++local.blockId; @@ -122,8 +118,7 @@ library LibVerifying { local.blockHash = ts.blockHash; local.prover = ts.prover; - provers[local.numBlocksVerified] = local.prover; - bonds[local.numBlocksVerified] = ts.validityBond; + LibBonds.creditBond(_state, local.prover, ts.validityBond); // Note: We exclusively address the bonds linked to the // transition used for verification. While there may exist @@ -160,14 +155,6 @@ library LibVerifying { _state.slotB.lastVerifiedBlockId = lastVerifiedBlockId; _state.blocks[local.slot].verifiedTransitionId = local.lastVerifiedTransitionId; - // Resize the provers and bonds array - uint256 newLen = local.numBlocksVerified; - assembly { - mstore(provers, newLen) - mstore(bonds, newLen) - } - if (!_tko.batchTransfer(provers, bonds)) revert L1_BATCH_TRANSFER_FAILED(); - if (local.syncStateRoot != 0) { _state.slotA.lastSyncedBlockId = local.syncBlockId; _state.slotA.lastSynecdAt = uint64(block.timestamp); diff --git a/packages/protocol/contracts/team/proving/ProverSet.sol b/packages/protocol/contracts/team/proving/ProverSet.sol index fda520e724..7eb1537a22 100644 --- a/packages/protocol/contracts/team/proving/ProverSet.sol +++ b/packages/protocol/contracts/team/proving/ProverSet.sol @@ -95,6 +95,16 @@ contract ProverSet is EssentialContract, IERC1271 { ITaikoL1(taikoL1()).proveBlock(_blockId, _input); } + /// @notice Deposits Taiko token to TaikoL1 contract. + function depositBond(uint256 _amount) external onlyAuthorized nonReentrant { + ITaikoL1(taikoL1()).depositBond(_amount); + } + + /// @notice Withdraws Taiko token from TaikoL1 contract. + function withdrawBond(uint256 _amount) external onlyAuthorized nonReentrant { + ITaikoL1(taikoL1()).withdrawBond(_amount); + } + /// @notice Delegates token voting right to a delegatee. /// @param _delegatee The delegatee to receive the voting right. function delegate(address _delegatee) external onlyAuthorized nonReentrant { diff --git a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol index 600dfed94d..6f36f4a4d4 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol @@ -33,7 +33,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); } // Prove the block @@ -79,7 +79,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { provenAt = ts.timestamp; - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); } console2.log("====== Verify block"); @@ -103,7 +103,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); } } @@ -137,7 +137,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); } // Prove the block @@ -171,7 +171,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { provenAt = ts.timestamp; - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.validityBond); } console2.log("====== Verify block"); @@ -195,8 +195,8 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether); } } @@ -246,8 +246,8 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether); } } @@ -297,7 +297,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.validityBond); } } @@ -348,7 +348,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Alice), 10_000 ether - L1.getConfig().livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - L1.getConfig().livenessBond); } } // Test summary: @@ -382,7 +382,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); } // Prove the block @@ -416,7 +416,9 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { provenAt = ts.timestamp; - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond - livenessBond); + assertEq( + totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond - livenessBond + ); } console2.log("====== Verify block"); @@ -440,7 +442,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); } } @@ -469,7 +471,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup10.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup10.t.sol index 174758de62..d146bbae97 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup10.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup10.t.sol @@ -39,7 +39,7 @@ contract TaikoL10TestGroup1 is TaikoL1TestGroupBase { (, TaikoData.SlotB memory b) = L1.getStateVariables(); assertEq(b.lastVerifiedBlockId, 5); - assertEq(tko.balanceOf(Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol index faf4a6e5f1..bbadc22c78 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol @@ -55,8 +55,8 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); } console2.log("====== William proves Alice is right"); @@ -80,10 +80,10 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); assertEq( - tko.balanceOf(William), + totalTkoBalance(tko, L1, William), 10_000 ether - tierSgx.validityBond + tierOp.contestBond * 7 / 8 ); } @@ -106,7 +106,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.prover, William); - assertEq(tko.balanceOf(William), 10_000 ether + tierOp.contestBond * 7 / 8); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether + tierOp.contestBond * 7 / 8); } } @@ -161,8 +161,8 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); } console2.log("====== William proves Tayler is right"); @@ -186,11 +186,14 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; - assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); - assertEq(tko.balanceOf(William), 10_000 ether - tierSgx.validityBond + quarterReward); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + quarterReward * 3); + assertEq( + totalTkoBalance(tko, L1, William), + 10_000 ether - tierSgx.validityBond + quarterReward + ); } console2.log("====== Verify the block"); @@ -212,11 +215,11 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; - assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); - assertEq(tko.balanceOf(William), 10_000 ether + quarterReward); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + quarterReward * 3); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether + quarterReward); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol index 5c63712b1b..d0e59155d6 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol @@ -58,9 +58,9 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, James); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, James), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); } console2.log("====== William proves James is right"); @@ -84,10 +84,10 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); assertEq( - tko.balanceOf(William), + totalTkoBalance(tko, L1, William), 10_000 ether - tierSgx.validityBond + tierOp.contestBond * 7 / 8 ); } @@ -110,7 +110,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.prover, William); - assertEq(tko.balanceOf(William), 10_000 ether + tierOp.contestBond * 7 / 8); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether + tierOp.contestBond * 7 / 8); } } @@ -168,9 +168,9 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, James); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, James), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); } console2.log("====== William proves Tayler is right"); @@ -194,12 +194,15 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, James), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; - assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); - assertEq(tko.balanceOf(William), 10_000 ether - tierSgx.validityBond + quarterReward); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + quarterReward * 3); + assertEq( + totalTkoBalance(tko, L1, William), + 10_000 ether - tierSgx.validityBond + quarterReward + ); } console2.log("====== Verify the block"); @@ -221,12 +224,12 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; - assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); - assertEq(tko.balanceOf(William), 10_000 ether + quarterReward); + assertEq(totalTkoBalance(tko, L1, James), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + quarterReward * 3); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether + quarterReward); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol index 52e2754f55..f0a4892f66 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol @@ -53,7 +53,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); assertEq( tko.balanceOf(Taylor), 10_000 ether - tierSgx.validityBond + tierOp.validityBond * 7 / 8 @@ -78,7 +78,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.prover, Taylor); - assertEq(tko.balanceOf(Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); } } @@ -134,7 +134,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); assertEq( tko.balanceOf(Taylor), @@ -160,7 +160,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.prover, Taylor); - assertEq(tko.balanceOf(Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol index 5cc6efc460..df449095b8 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol @@ -45,8 +45,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Guardian re-approve with the same transition"); @@ -84,8 +84,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== William contests with a lower tier proof"); @@ -118,8 +118,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -183,8 +183,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Verify the block"); @@ -205,8 +205,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -273,9 +273,9 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Verify the block"); @@ -296,9 +296,9 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -340,8 +340,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - L1.getConfig().livenessBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - L1.getConfig().livenessBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol index 6192531c5a..ce36eb7e92 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol @@ -56,9 +56,9 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); // not zero - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); assertEq( - tko.balanceOf(Alice), + totalTkoBalance(tko, L1, Alice), 10_000 ether - tierSgx.validityBond + tierOp.contestBond * 7 / 8 ); } @@ -81,8 +81,8 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.prover, Alice); - assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); - assertEq(tko.balanceOf(Alice), 10_000 ether + tierOp.contestBond * 7 / 8); + assertEq(totalTkoBalance(tko, L1, Taylor), 10_000 ether - tierOp.contestBond); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether + tierOp.contestBond * 7 / 8); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol index b00053f391..16bd04a3f5 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup9.t.sol @@ -67,8 +67,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Guardian re-approve with the same transition"); @@ -107,8 +107,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== William contests with a lower tier proof"); @@ -142,8 +142,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -208,8 +208,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Verify the block"); @@ -231,8 +231,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -300,9 +300,9 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(Carol), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Carol), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } console2.log("====== Verify the block"); @@ -324,9 +324,9 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); - assertEq(tko.balanceOf(Carol), 10_000 ether - tierOp.validityBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - livenessBond); + assertEq(totalTkoBalance(tko, L1, Carol), 10_000 ether - tierOp.validityBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } @@ -369,8 +369,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Alice), 10_000 ether - L1.getConfig().livenessBond); - assertEq(tko.balanceOf(William), 10_000 ether); + assertEq(totalTkoBalance(tko, L1, Alice), 10_000 ether - L1.getConfig().livenessBond); + assertEq(totalTkoBalance(tko, L1, William), 10_000 ether); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroupBase.sol b/packages/protocol/test/L1/TaikoL1TestGroupBase.sol index a57dbebec3..0902555208 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroupBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroupBase.sol @@ -129,6 +129,18 @@ abstract contract TaikoL1TestGroupBase is TaikoL1TestBase { } } + function totalTkoBalance( + TaikoToken tko, + TaikoL1 L1, + address user + ) + internal + view + returns (uint256) + { + return tko.balanceOf(user) + L1.bondBalanceOf(user); + } + function printBlock(TaikoData.Block memory blk) internal view { (, TaikoData.SlotB memory b) = L1.getStateVariables(); console2.log("---CHAIN:");