diff --git a/snapshots/BetterCPUInlineGasTest.json b/snapshots/BetterCPUInlineGasTest.json index ae3a2b0a..b2978ec6 100644 --- a/snapshots/BetterCPUInlineGasTest.json +++ b/snapshots/BetterCPUInlineGasTest.json @@ -1,8 +1,8 @@ { - "Flag0_P0ForcedSwitch": "22701", - "Turn0_Lead": "104410", - "Turn1_BothAttack": "262381", - "Turn2_BothAttack": "236457", - "Turn3_BothAttack": "232481", - "Turn4_BothAttack": "232485" + "Flag0_P0ForcedSwitch": "22763", + "Turn0_Lead": "104184", + "Turn1_BothAttack": "264088", + "Turn2_BothAttack": "238164", + "Turn3_BothAttack": "234188", + "Turn4_BothAttack": "234192" } \ No newline at end of file diff --git a/snapshots/EngineGasTest.json b/snapshots/EngineGasTest.json index 844a9603..8d0b40ce 100644 --- a/snapshots/EngineGasTest.json +++ b/snapshots/EngineGasTest.json @@ -1,21 +1,21 @@ { - "B1_Execute": "889458", - "B1_Setup": "816408", - "B2_Execute": "645719", - "B2_Setup": "282218", - "Battle1_Execute": "449877", - "Battle1_Setup": "791633", - "Battle2_Execute": "367369", - "Battle2_Setup": "233097", - "External_Execute": "456527", - "External_Setup": "782348", - "FirstBattle": "2906000", - "Inline_Execute": "318805", - "Inline_Setup": "225023", + "B1_Execute": "889886", + "B1_Setup": "816459", + "B2_Execute": "648291", + "B2_Setup": "282290", + "Battle1_Execute": "449213", + "Battle1_Setup": "791685", + "Battle2_Execute": "368905", + "Battle2_Setup": "233149", + "External_Execute": "456719", + "External_Setup": "782400", + "FirstBattle": "2911711", + "Inline_Execute": "320015", + "Inline_Setup": "225083", "Intermediary stuff": "44458", - "SecondBattle": "2927592", - "Setup 1": "1670484", - "Setup 2": "292493", - "Setup 3": "332770", - "ThirdBattle": "2274723" + "SecondBattle": "2936650", + "Setup 1": "1670530", + "Setup 2": "292539", + "Setup 3": "332805", + "ThirdBattle": "2282494" } \ No newline at end of file diff --git a/snapshots/EngineOptimizationTest.json b/snapshots/EngineOptimizationTest.json index 883b347d..09b37c45 100644 --- a/snapshots/EngineOptimizationTest.json +++ b/snapshots/EngineOptimizationTest.json @@ -1,4 +1,4 @@ { - "ExternalStaminaRegen": "390772", - "InlineStaminaRegen": "999942" + "ExternalStaminaRegen": "392424", + "InlineStaminaRegen": "999051" } \ No newline at end of file diff --git a/snapshots/FullyOptimizedInlineGasTest.json b/snapshots/FullyOptimizedInlineGasTest.json index 3edf6547..66ef6ab8 100644 --- a/snapshots/FullyOptimizedInlineGasTest.json +++ b/snapshots/FullyOptimizedInlineGasTest.json @@ -1,8 +1,8 @@ { - "Fast_Battle1": "1802444", - "Fast_Battle2": "1704099", - "Fast_Battle3": "1221705", - "Fast_Setup_1": "1321867", - "Fast_Setup_2": "216314", - "Fast_Setup_3": "212698" + "Fast_Battle1": "1867564", + "Fast_Battle2": "1777864", + "Fast_Battle3": "1288656", + "Fast_Setup_1": "1322088", + "Fast_Setup_2": "216706", + "Fast_Setup_3": "212909" } \ No newline at end of file diff --git a/snapshots/InlineEngineGasTest.json b/snapshots/InlineEngineGasTest.json index ffc94073..d4833e98 100644 --- a/snapshots/InlineEngineGasTest.json +++ b/snapshots/InlineEngineGasTest.json @@ -1,16 +1,16 @@ { - "B1_Execute": "870357", - "B1_Setup": "758497", - "B2_Execute": "604941", - "B2_Setup": "271670", - "Battle1_Execute": "402355", - "Battle1_Setup": "733715", - "Battle2_Execute": "318757", - "Battle2_Setup": "224451", - "FirstBattle": "2595237", - "SecondBattle": "2580140", - "Setup 1": "1612152", - "Setup 2": "318169", - "Setup 3": "314901", - "ThirdBattle": "1964987" + "B1_Execute": "870101", + "B1_Setup": "758557", + "B2_Execute": "606857", + "B2_Setup": "271758", + "Battle1_Execute": "401230", + "Battle1_Setup": "733775", + "Battle2_Execute": "319832", + "Battle2_Setup": "224511", + "FirstBattle": "2595770", + "SecondBattle": "2583418", + "Setup 1": "1612191", + "Setup 2": "318239", + "Setup 3": "314704", + "ThirdBattle": "1967495" } \ No newline at end of file diff --git a/snapshots/MatchmakerTest.json b/snapshots/MatchmakerTest.json index 9b3b0b0c..344f7a99 100644 --- a/snapshots/MatchmakerTest.json +++ b/snapshots/MatchmakerTest.json @@ -1,5 +1,5 @@ { - "Accept1": "307765", - "Accept2": "34130", - "Propose1": "197286" + "Accept1": "307809", + "Accept2": "34162", + "Propose1": "197318" } \ No newline at end of file diff --git a/src/DefaultValidator.sol b/src/DefaultValidator.sol index d2659ed1..e9f35c71 100644 --- a/src/DefaultValidator.sol +++ b/src/DefaultValidator.sol @@ -103,7 +103,7 @@ contract DefaultValidator is IValidator { bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, - uint240 extraData + uint16 extraData ) public view returns (bool) { BattleContext memory ctx = ENGINE.getBattleContext(battleKey); uint256 activeMonIndex = (playerIndex == 0) ? ctx.p0ActiveMonIndex : ctx.p1ActiveMonIndex; @@ -127,7 +127,7 @@ contract DefaultValidator is IValidator { } // Validates that you can't switch to the same mon, you have enough stamina, the move isn't disabled, etc. - function validatePlayerMove(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint240 extraData) + function validatePlayerMove(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint16 extraData) external view returns (bool) @@ -191,7 +191,7 @@ contract DefaultValidator is IValidator { bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, - uint240 extraData, + uint16 extraData, uint256 activeMonIndex, ValidationContext memory vctx ) internal view returns (bool) { diff --git a/src/Engine.sol b/src/Engine.sol index 4f608183..4a42d10d 100644 --- a/src/Engine.sol +++ b/src/Engine.sol @@ -46,8 +46,8 @@ contract Engine is IEngine, MappingAllocator { // A non-zero encoded move is the "transient is populated for this call" signal. uint256 private transient _turnP0MoveEncoded; uint256 private transient _turnP1MoveEncoded; - bytes32 private transient _turnP0Salt; - bytes32 private transient _turnP1Salt; + uint104 private transient _turnP0Salt; + uint104 private transient _turnP1Salt; // Errors error NoWriteAllowed(); @@ -65,7 +65,7 @@ contract Engine is IEngine, MappingAllocator { // Events event BattleStart(bytes32 indexed battleKey, address p0, address p1); event MonMove( - bytes32 indexed battleKey, uint256 packedPlayerIndexMonIndex, uint256 packedMoveIndexExtraData, bytes32 salt + bytes32 indexed battleKey, uint256 packedPlayerIndexMonIndex, uint256 packedMoveIndexExtraData, uint104 salt ); event EngineExecute(bytes32 indexed battleKey); event BattleComplete(bytes32 indexed battleKey, address winner); @@ -300,11 +300,11 @@ contract Engine is IEngine, MappingAllocator { function executeWithMoves( bytes32 battleKey, uint8 p0MoveIndex, - bytes32 p0Salt, - uint240 p0ExtraData, + uint104 p0Salt, + uint16 p0ExtraData, uint8 p1MoveIndex, - bytes32 p1Salt, - uint240 p1ExtraData + uint104 p1Salt, + uint16 p1ExtraData ) external { bytes32 storageKey = _getStorageKey(battleKey); storageKeyForWrite = storageKey; @@ -329,7 +329,7 @@ contract Engine is IEngine, MappingAllocator { /// @notice Combined single-player setMove + execute for forced switch turns /// @dev Only callable by moveManager. The acting player is inferred from battle.playerSwitchForTurnFlag. - function executeWithSingleMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData) external { + function executeWithSingleMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData) external { bytes32 storageKey = _getStorageKey(battleKey); storageKeyForWrite = storageKey; @@ -358,12 +358,12 @@ contract Engine is IEngine, MappingAllocator { _executeInternal(battleKey, storageKey); } - /// @dev Decodes a transient-encoded move (layout: [extraData:240 | packedMoveIndex:8]) into a + /// @dev Decodes a transient-encoded move (layout: [extraData:16 | packedMoveIndex:8]) into a /// MoveDecision. Encoded == 0 means "no current turn move" since packedMoveIndex always has /// IS_REAL_TURN_BIT set for a real move. function _decodeMove(uint256 encoded) private pure returns (MoveDecision memory m) { m.packedMoveIndex = uint8(encoded & 0xFF); - m.extraData = uint240(encoded >> 8); + m.extraData = uint16(encoded >> 8); } /// @dev Returns the current turn's MoveDecision for `playerIndex`. During an active @@ -381,7 +381,7 @@ contract Engine is IEngine, MappingAllocator { } /// @dev Salt companion to `_getCurrentTurnMove`. - function _getCurrentTurnSalt(BattleConfig storage config, uint256 playerIndex) internal view returns (bytes32) { + function _getCurrentTurnSalt(BattleConfig storage config, uint256 playerIndex) internal view returns (uint104) { uint256 encoded = playerIndex == 0 ? _turnP0MoveEncoded : _turnP1MoveEncoded; if (encoded != 0) { return playerIndex == 0 ? _turnP0Salt : _turnP1Salt; @@ -481,12 +481,12 @@ contract Engine is IEngine, MappingAllocator { // Update the temporary RNG to the newest value // Inline RNG computation when oracle is address(0) to avoid external call uint256 rng; - bytes32 p0TurnSalt = _getCurrentTurnSalt(config, 0); - bytes32 p1TurnSalt = _getCurrentTurnSalt(config, 1); + uint104 p0TurnSalt = _getCurrentTurnSalt(config, 0); + uint104 p1TurnSalt = _getCurrentTurnSalt(config, 1); if (address(config.rngOracle) == address(0)) { rng = uint256(keccak256(abi.encode(p0TurnSalt, p1TurnSalt))); } else { - rng = config.rngOracle.getRNG(p0TurnSalt, p1TurnSalt); + rng = config.rngOracle.getRNG(bytes32(uint256(p0TurnSalt)), bytes32(uint256(p1TurnSalt))); } tempRNG = rng; @@ -730,8 +730,8 @@ contract Engine is IEngine, MappingAllocator { function resetCallContext() external { _turnP0MoveEncoded = 0; _turnP1MoveEncoded = 0; - _turnP0Salt = bytes32(0); - _turnP1Salt = bytes32(0); + _turnP0Salt = 0; + _turnP1Salt = 0; } function end(bytes32 battleKey) external { @@ -1377,8 +1377,8 @@ contract Engine is IEngine, MappingAllocator { BattleConfig storage config, uint256 playerIndex, uint8 moveIndex, - bytes32 salt, - uint240 extraData + uint104 salt, + uint16 extraData ) internal { // Pack moveIndex with isRealTurn bit and apply +1 offset for regular moves // Regular moves (< SWITCH_MOVE_INDEX) are stored as moveIndex + 1 to avoid zero ambiguity @@ -1395,7 +1395,7 @@ contract Engine is IEngine, MappingAllocator { } } - function setMove(bytes32 battleKey, uint256 playerIndex, uint8 moveIndex, bytes32 salt, uint240 extraData) + function setMove(bytes32 battleKey, uint256 playerIndex, uint8 moveIndex, uint104 salt, uint16 extraData) external { bool isInsideExecute = _turnP0MoveEncoded != 0 || _turnP1MoveEncoded != 0; @@ -1565,7 +1565,7 @@ contract Engine is IEngine, MappingAllocator { // check below silently no-ops and timeout handles the stuck player. if ((battle.turnId == 0 || currentMonState.isKnockedOut) && moveIndex != SWITCH_MOVE_INDEX) { moveIndex = SWITCH_MOVE_INDEX; - move.extraData = uint240(0); + move.extraData = uint16(0); } // Handle a switch, no-op, or regular move. @@ -2391,7 +2391,7 @@ contract Engine is IEngine, MappingAllocator { /// @notice Validates a player move, handling both inline validation (when validator is address(0)) and external validators /// @dev This allows callers like CPU to validate moves without needing to handle the address(0) case themselves - function validatePlayerMoveForBattle(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint240 extraData) + function validatePlayerMoveForBattle(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint16 extraData) external returns (bool) { diff --git a/src/IEngine.sol b/src/IEngine.sol index 3dd7273f..a75b3e1d 100644 --- a/src/IEngine.sol +++ b/src/IEngine.sol @@ -37,18 +37,18 @@ interface IEngine { uint256 rng ) external returns (int32 damage, bytes32 eventType); function switchActiveMon(uint256 playerIndex, uint256 monToSwitchIndex) external; - function setMove(bytes32 battleKey, uint256 playerIndex, uint8 moveIndex, bytes32 salt, uint240 extraData) external; + function setMove(bytes32 battleKey, uint256 playerIndex, uint8 moveIndex, uint104 salt, uint16 extraData) external; function execute(bytes32 battleKey) external; function executeWithMoves( bytes32 battleKey, uint8 p0MoveIndex, - bytes32 p0Salt, - uint240 p0ExtraData, + uint104 p0Salt, + uint16 p0ExtraData, uint8 p1MoveIndex, - bytes32 p1Salt, - uint240 p1ExtraData + uint104 p1Salt, + uint16 p1ExtraData ) external; - function executeWithSingleMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData) external; + function executeWithSingleMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData) external; function resetCallContext() external; // Getters @@ -94,7 +94,7 @@ interface IEngine { function getPlayerSwitchForTurnFlagForBattleState(bytes32 battleKey) external view returns (uint256); function getGlobalKV(bytes32 battleKey, uint64 key) external view returns (uint192); function getBattleValidator(bytes32 battleKey) external view returns (IValidator); - function validatePlayerMoveForBattle(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint240 extraData) + function validatePlayerMoveForBattle(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint16 extraData) external returns (bool); function getEffects(bytes32 battleKey, uint256 targetIndex, uint256 monIndex) diff --git a/src/IValidator.sol b/src/IValidator.sol index 8dea5f1d..2f71e565 100644 --- a/src/IValidator.sol +++ b/src/IValidator.sol @@ -11,7 +11,7 @@ interface IValidator { ) external returns (bool); // Validates that you can't switch to the same mon, you have enough stamina, the move isn't disabled, etc. - function validatePlayerMove(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint240 extraData) + function validatePlayerMove(bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, uint16 extraData) external returns (bool); @@ -20,7 +20,7 @@ interface IValidator { bytes32 battleKey, uint256 moveIndex, uint256 playerIndex, - uint240 extraData + uint16 extraData ) external returns (bool); // Validates that a switch is valid diff --git a/src/Structs.sol b/src/Structs.sol index 327a52ec..0504a330 100644 --- a/src/Structs.sol +++ b/src/Structs.sol @@ -47,11 +47,11 @@ struct Battle { IEngineHook[] engineHooks; } -// Packed into 1 storage slot (8 + 240 = 248 bits) +// Packed into 1 storage slot (8 + 16 = 24 bits) // packedMoveIndex: lower 7 bits = moveIndex (0-127), bit 7 = isRealTurn (1 = real, 0 = not set) struct MoveDecision { uint8 packedMoveIndex; - uint240 extraData; + uint16 extraData; } // Stored by the Engine, tracks immutable battle data and battle state @@ -81,8 +81,8 @@ struct BattleConfig { uint40 startTimestamp; // 40 — battle start time; overflows in year ~36825 (shrunk from uint48 for slot-2 packing) bool hasInlineStaminaRegen; // 8 uint8 globalKVCount; // 8 — live entry count in the current battle's globalKV key buffer - bytes32 p0Salt; - bytes32 p1Salt; + uint104 p0Salt; + uint104 p1Salt; MoveDecision p0Move; MoveDecision p1Move; mapping(uint256 index => Mon) p0Team; @@ -118,8 +118,8 @@ struct BattleConfigView { uint96 packedP1EffectsCount; uint8 teamSizes; uint40 startTimestamp; // Needed client-side for the getGlobalKV freshness gate - bytes32 p0Salt; - bytes32 p1Salt; + uint104 p0Salt; + uint104 p1Salt; MoveDecision p0Move; MoveDecision p1Move; EffectInstance[] globalEffects; @@ -185,8 +185,8 @@ struct PlayerDecisionData { struct RevealedMove { uint8 moveIndex; - uint240 extraData; - bytes32 salt; + uint16 extraData; + uint104 salt; } // Used for StatBoosts diff --git a/src/commit-manager/DefaultCommitManager.sol b/src/commit-manager/DefaultCommitManager.sol index e2190275..d681cbeb 100644 --- a/src/commit-manager/DefaultCommitManager.sol +++ b/src/commit-manager/DefaultCommitManager.sol @@ -118,7 +118,7 @@ contract DefaultCommitManager is ICommitManager { emit MoveCommit(battleKey, caller); } - function revealMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData, bool autoExecute) + function revealMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData, bool autoExecute) external { // Get all battle context in one call diff --git a/src/commit-manager/ICommitManager.sol b/src/commit-manager/ICommitManager.sol index f9e25bb5..f666c1d8 100644 --- a/src/commit-manager/ICommitManager.sol +++ b/src/commit-manager/ICommitManager.sol @@ -5,7 +5,7 @@ import "../Structs.sol"; interface ICommitManager { function commitMove(bytes32 battleKey, bytes32 moveHash) external; - function revealMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData, bool autoExecute) + function revealMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData, bool autoExecute) external; function getCommitment(bytes32 battleKey, address player) external view returns (bytes32 moveHash, uint256 turnId); function getMoveCountForBattleState(bytes32 battleKey, address player) external view returns (uint256); diff --git a/src/commit-manager/SignedCommitLib.sol b/src/commit-manager/SignedCommitLib.sol index 4646d4ee..3342a749 100644 --- a/src/commit-manager/SignedCommitLib.sol +++ b/src/commit-manager/SignedCommitLib.sol @@ -40,14 +40,14 @@ library SignedCommitLib { uint64 turnId; bytes32 committerMoveHash; // A's hash that B signs over uint8 revealerMoveIndex; - bytes32 revealerSalt; - uint240 revealerExtraData; + uint104 revealerSalt; + uint16 revealerExtraData; } /// @notice Computes the type hash for DualSignedReveal function computeDualSignedRevealTypehash() internal pure returns (bytes32) { return keccak256( - "DualSignedReveal(bytes32 battleKey,uint64 turnId,bytes32 committerMoveHash,uint8 revealerMoveIndex,bytes32 revealerSalt,uint240 revealerExtraData)" + "DualSignedReveal(bytes32 battleKey,uint64 turnId,bytes32 committerMoveHash,uint8 revealerMoveIndex,uint104 revealerSalt,uint16 revealerExtraData)" ); } @@ -58,7 +58,7 @@ library SignedCommitLib { return keccak256( abi.encode( keccak256( - "DualSignedReveal(bytes32 battleKey,uint64 turnId,bytes32 committerMoveHash,uint8 revealerMoveIndex,bytes32 revealerSalt,uint240 revealerExtraData)" + "DualSignedReveal(bytes32 battleKey,uint64 turnId,bytes32 committerMoveHash,uint8 revealerMoveIndex,uint104 revealerSalt,uint16 revealerExtraData)" ), reveal.battleKey, reveal.turnId, diff --git a/src/commit-manager/SignedCommitManager.sol b/src/commit-manager/SignedCommitManager.sol index 20bd4aaf..aa0831fa 100644 --- a/src/commit-manager/SignedCommitManager.sol +++ b/src/commit-manager/SignedCommitManager.sol @@ -20,13 +20,16 @@ import {SignedCommitLib} from "./SignedCommitLib.sol"; /// 3. Alice reveals (TX 3) /// /// Dual-signed flow (1 transaction): -/// 1. Alice signs her move hash off-chain, sends to Bob -/// 2. Bob signs his move + Alice's hash off-chain, sends to Alice -/// 3. Alice calls executeWithDualSignedMoves with both moves + Bob's signature (TX 1) +/// 1. Alice signs her move hash off-chain (SignedCommit), sends to Bob +/// 2. Bob signs his move + Alice's hash off-chain (DualSignedReveal), sends back +/// 3. Anyone (Alice, Bob, or a relayer) calls executeWithDualSignedMoves with +/// both signatures + Alice's preimage (TX 1) /// -/// Security: Alice commits to her hash before seeing Bob's move. Bob signs over -/// Alice's hash, so even though Alice sees Bob's move before submitting, Alice -/// cannot change her move (must provide valid preimage for the hash Bob signed). +/// Security: Alice commits to her hash before seeing Bob's move (binding Alice +/// cryptographically via her SignedCommit). Bob signs over Alice's hash (binding +/// Bob via his DualSignedReveal). Both signatures together prove both players' +/// intent without trusting msg.sender — submission can be relayed without +/// reopening any unilateral-revealer attack. /// /// Fallback if Alice stalls: Bob can use commitWithSignature() to publish Alice's /// signed commitment on-chain, then continue with the normal reveal flow. @@ -36,9 +39,6 @@ contract SignedCommitManager is DefaultCommitManager, EIP712 { /// @notice Thrown when the signature verification fails error InvalidSignature(); - /// @notice Thrown when caller is not the committing player for this turn - error CallerNotCommitter(); - /// @notice Thrown when trying to use dual-signed flow on a single-player turn error NotTwoPlayerTurn(); @@ -54,8 +54,12 @@ contract SignedCommitManager is DefaultCommitManager, EIP712 { } /// @notice Executes a turn using dual-signed moves from both players (gas-optimized) - /// @dev The committer (A) submits both moves. The revealer (B) has signed over - /// their move and A's move hash, binding both players to their moves. + /// @dev Both players sign off-chain — committer over `SignedCommit{committerMoveHash, …}` + /// and revealer over `DualSignedReveal{committerMoveHash, …, revealerMove…}`. Anyone + /// can submit (relayer-friendly) since both signatures are required and bind each + /// player independently. Without the explicit committer signature, a malicious + /// revealer could pick any preimage `P*`, sign `DualSignedReveal{keccak(P*), …}` + /// and play `P*` as the committer's move — the committer signature closes that. /// @param battleKey The battle identifier /// @param committerMoveIndex The committer's move index /// @param committerSalt The committer's salt @@ -63,48 +67,54 @@ contract SignedCommitManager is DefaultCommitManager, EIP712 { /// @param revealerMoveIndex The revealer's move index /// @param revealerSalt The revealer's salt /// @param revealerExtraData The revealer's extra data + /// @param committerSignature EIP-712 signature from the committer over + /// SignedCommit(committerMoveHash, battleKey, turnId) /// @param revealerSignature EIP-712 signature from the revealer over - /// DualSignedReveal(battleKey, turnId, committerMoveHash, revealerMove...) + /// DualSignedReveal(battleKey, turnId, committerMoveHash, revealerMove…) function executeWithDualSignedMoves( bytes32 battleKey, uint8 committerMoveIndex, - bytes32 committerSalt, - uint240 committerExtraData, + uint104 committerSalt, + uint16 committerExtraData, uint8 revealerMoveIndex, - bytes32 revealerSalt, - uint240 revealerExtraData, + uint104 revealerSalt, + uint16 revealerExtraData, + bytes calldata committerSignature, bytes calldata revealerSignature ) external { - // Use lightweight getter (validates internally, reverts on bad state) (address committer, address revealer, uint64 turnId) = ENGINE.getCommitAuthForDualSigned(battleKey); - // Caller must be the committing player - if (msg.sender != committer) { - revert CallerNotCommitter(); - } - - // Compute the committer's move hash bytes32 committerMoveHash = keccak256(abi.encodePacked(committerMoveIndex, committerSalt, committerExtraData)); - // Verify the revealer's signature over DualSignedReveal - SignedCommitLib.DualSignedReveal memory reveal = SignedCommitLib.DualSignedReveal({ - battleKey: battleKey, - turnId: turnId, - committerMoveHash: committerMoveHash, - revealerMoveIndex: revealerMoveIndex, - revealerSalt: revealerSalt, - revealerExtraData: revealerExtraData - }); - - bytes32 digest = _hashTypedData(SignedCommitLib.hashDualSignedReveal(reveal)); - if (ECDSA.recoverCalldata(digest, revealerSignature) != revealer) { - revert InvalidSignature(); + // Scoped to keep `commit`/`reveal` structs from sharing stack space across recoveries. + { + SignedCommitLib.SignedCommit memory commit = SignedCommitLib.SignedCommit({ + moveHash: committerMoveHash, + battleKey: battleKey, + turnId: turnId + }); + bytes32 commitDigest = _hashTypedData(SignedCommitLib.hashSignedCommit(commit)); + if (ECDSA.recoverCalldata(commitDigest, committerSignature) != committer) { + revert InvalidSignature(); + } + } + + { + SignedCommitLib.DualSignedReveal memory reveal = SignedCommitLib.DualSignedReveal({ + battleKey: battleKey, + turnId: turnId, + committerMoveHash: committerMoveHash, + revealerMoveIndex: revealerMoveIndex, + revealerSalt: revealerSalt, + revealerExtraData: revealerExtraData + }); + bytes32 revealDigest = _hashTypedData(SignedCommitLib.hashDualSignedReveal(reveal)); + if (ECDSA.recoverCalldata(revealDigest, revealerSignature) != revealer) { + revert InvalidSignature(); + } } - // Execute with moves in a single call (engine validates during execution) - // No playerData updates needed - engine tracks lastExecuteTimestamp for timeouts if (turnId % 2 == 0) { - // Committer is p0 ENGINE.executeWithMoves( battleKey, committerMoveIndex, @@ -115,7 +125,6 @@ contract SignedCommitManager is DefaultCommitManager, EIP712 { revealerExtraData ); } else { - // Committer is p1 ENGINE.executeWithMoves( battleKey, revealerMoveIndex, @@ -130,7 +139,7 @@ contract SignedCommitManager is DefaultCommitManager, EIP712 { /// @notice Executes a forced single-player move, usually a switch after a KO, in one transaction. /// @dev The acting player is inferred from the engine's switch flag and must be msg.sender. - function executeSinglePlayerMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData) external { + function executeSinglePlayerMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData) external { CommitContext memory ctx = ENGINE.getCommitContext(battleKey); if (ctx.startTimestamp == 0) { diff --git a/src/cpu/BetterCPU.sol b/src/cpu/BetterCPU.sol index 68077cc9..4a1cbec0 100644 --- a/src/cpu/BetterCPU.sol +++ b/src/cpu/BetterCPU.sol @@ -56,10 +56,10 @@ contract BetterCPU is CPU { // ============ CORE DECISION TREE ============ - function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint240 playerExtraData) + function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint16 playerExtraData) external override - returns (uint128 moveIndex, uint240 extraData) + returns (uint128 moveIndex, uint16 extraData) { (RevealedMove[] memory noOp, RevealedMove[] memory moves, RevealedMove[] memory switches) = _calculateValidMoves(ctx); @@ -380,9 +380,9 @@ contract BetterCPU is CPU { // ============ LEAD SELECTION ============ /// @notice Select lead with dual-type scoring (defensive + offensive) - function _selectLead(bytes32 battleKey, uint240 opponentMonExtraData, RevealedMove[] memory switches) + function _selectLead(bytes32 battleKey, uint16 opponentMonExtraData, RevealedMove[] memory switches) internal - returns (uint128, uint240) + returns (uint128, uint16) { MonStats memory oppStats = ENGINE.getMonStatsForBattle(battleKey, 0, uint256(opponentMonExtraData)); Type oppType1 = oppStats.type1; @@ -445,7 +445,7 @@ contract BetterCPU is CPU { uint256 opponentMonIndex, uint8 opponentMoveIndex, RevealedMove[] memory switches - ) internal view returns (uint128, uint240) { + ) internal view returns (uint128, uint16) { // If opponent isn't attacking, fall back to random if (opponentMoveIndex >= SWITCH_MOVE_INDEX) { return (switches[0].moveIndex, switches[0].extraData); diff --git a/src/cpu/CPU.sol b/src/cpu/CPU.sol index e5553cc8..b48b1a93 100644 --- a/src/cpu/CPU.sol +++ b/src/cpu/CPU.sol @@ -34,10 +34,10 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { * If it's turn 0, randomly selects a mon index to swap to * Otherwise, randomly selects a valid move, switch index, or no op */ - function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint240 playerExtraData) + function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint16 playerExtraData) external virtual - returns (uint128 moveIndex, uint240 extraData); + returns (uint128 moveIndex, uint16 extraData); /** * Public test-friendly wrapper: fetches context and forwards. playerIndex is ignored @@ -63,7 +63,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { uint256 teamSize = ctx.p1TeamSize; RevealedMove[] memory switchChoices = new RevealedMove[](teamSize); for (uint256 i = 0; i < teamSize; i++) { - switchChoices[i] = RevealedMove({moveIndex: SWITCH_MOVE_INDEX, salt: "", extraData: uint240(i)}); + switchChoices[i] = RevealedMove({moveIndex: SWITCH_MOVE_INDEX, salt: 0, extraData: uint16(i)}); } return (new RevealedMove[](0), new RevealedMove[](0), switchChoices); } @@ -77,7 +77,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { validSwitchIndices = new uint256[](teamSize); for (uint256 i = 0; i < teamSize; i++) { if (i != activeMonIndex) { - if (_validateCPUMove(ctx, SWITCH_MOVE_INDEX, uint240(i))) { + if (_validateCPUMove(ctx, SWITCH_MOVE_INDEX, uint16(i))) { validSwitchIndices[validSwitchCount++] = i; } } @@ -89,19 +89,19 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { for (uint256 i = 0; i < validSwitchCount; i++) { switchChoices[i] = RevealedMove({ moveIndex: SWITCH_MOVE_INDEX, - salt: "", - extraData: uint240(validSwitchIndices[i]) + salt: 0, + extraData: uint16(validSwitchIndices[i]) }); } return (new RevealedMove[](0), new RevealedMove[](0), switchChoices); } uint8[] memory validMoveIndices = new uint8[](NUM_MOVES); - uint240[] memory validMoveExtraData = new uint240[](NUM_MOVES); + uint16[] memory validMoveExtraData = new uint16[](NUM_MOVES); uint256 validMoveCount; // Check for valid moves for (uint256 i = 0; i < NUM_MOVES; i++) { uint256 rawMoveSlot = ctx.cpuActiveMonMoveSlots[i]; - uint240 extraDataToUse = 0; + uint16 extraDataToUse = 0; // Inline moves always have ExtraDataType.None — skip extraData logic if (!MoveSlotLib.isInline(rawMoveSlot)) { IMoveSet move = MoveSlotLib.toIMoveSet(rawMoveSlot); @@ -112,7 +112,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { } uint256 randomIndex = _sampleRNG(keccak256(abi.encode(nonce++, ctx.battleKey, block.timestamp))) % validSwitchCount; - extraDataToUse = uint240(validSwitchIndices[randomIndex]); + extraDataToUse = uint16(validSwitchIndices[randomIndex]); validMoveExtraData[validMoveCount] = extraDataToUse; } else if (move.extraDataType() == ExtraDataType.OpponentNonKOTeamIndex) { uint256 opponentTeamSize = ctx.p0TeamSize; @@ -129,7 +129,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { } uint256 randomIndex = _sampleRNG(keccak256(abi.encode(nonce++, ctx.battleKey, block.timestamp))) % validTargetCount; - extraDataToUse = uint240(validTargets[randomIndex]); + extraDataToUse = uint16(validTargets[randomIndex]); validMoveExtraData[validMoveCount] = extraDataToUse; } } @@ -141,15 +141,15 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { RevealedMove[] memory validMovesArray = new RevealedMove[](validMoveCount); for (uint256 i = 0; i < validMoveCount; i++) { validMovesArray[i] = - RevealedMove({moveIndex: validMoveIndices[i], salt: "", extraData: validMoveExtraData[i]}); + RevealedMove({moveIndex: validMoveIndices[i], salt: 0, extraData: validMoveExtraData[i]}); } RevealedMove[] memory validSwitchesArray = new RevealedMove[](validSwitchCount); for (uint256 i = 0; i < validSwitchCount; i++) { validSwitchesArray[i] = - RevealedMove({moveIndex: SWITCH_MOVE_INDEX, salt: "", extraData: uint240(validSwitchIndices[i])}); + RevealedMove({moveIndex: SWITCH_MOVE_INDEX, salt: 0, extraData: uint16(validSwitchIndices[i])}); } RevealedMove[] memory noOpArray = new RevealedMove[](1); - noOpArray[0] = RevealedMove({moveIndex: NO_OP_MOVE_INDEX, salt: "", extraData: 0}); + noOpArray[0] = RevealedMove({moveIndex: NO_OP_MOVE_INDEX, salt: 0, extraData: 0}); nonceToUse = nonce; return (noOpArray, validMovesArray, validSwitchesArray); @@ -172,7 +172,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { /// DEFAULT_MOVES_PER_MON / DEFAULT_MONS_PER_TEAM; the CPU's own iteration already bounds /// moveIndex below NUM_MOVES and monToSwitchIndex below p1TeamSize, so the basic/switch /// checks are equivalent to the engine-side versions. - function _validateCPUMove(CPUContext memory ctx, uint8 moveIndex, uint240 extraData) + function _validateCPUMove(CPUContext memory ctx, uint8 moveIndex, uint16 extraData) internal returns (bool) { @@ -182,7 +182,7 @@ abstract contract CPU is CPUMoveManager, ICPU, ICPURNG, IMatchmaker { return ENGINE.validatePlayerMoveForBattle(ctx.battleKey, moveIndex, 1, extraData); } - function _inlineValidateCPUMove(CPUContext memory ctx, uint8 moveIndex, uint240 extraData) + function _inlineValidateCPUMove(CPUContext memory ctx, uint8 moveIndex, uint16 extraData) private view returns (bool) diff --git a/src/cpu/CPUMoveManager.sol b/src/cpu/CPUMoveManager.sol index 734a03e6..1f286113 100644 --- a/src/cpu/CPUMoveManager.sol +++ b/src/cpu/CPUMoveManager.sol @@ -22,7 +22,7 @@ abstract contract CPUMoveManager { engine.updateMatchmakers(self, empty); } - function selectMove(bytes32 battleKey, uint8 moveIndex, bytes32 salt, uint240 extraData) external { + function selectMove(bytes32 battleKey, uint8 moveIndex, uint104 salt, uint16 extraData) external { // Cheap routing staticcall: one SLOAD for p0 / winnerIndex / playerSwitchForTurnFlag. // When the turn is "p0 forced switch" (flag == 0) or the game is already over we return // without ever paying for the full CPUContext (which would load team sizes, KO bitmaps, @@ -44,8 +44,10 @@ abstract contract CPUMoveManager { // P1's turn or both players move: CPU calculates its move. Fetch the full context now. CPUContext memory ctx = ENGINE.getCPUContext(battleKey); - (uint128 cpuMoveIndex, uint240 cpuExtraData) = ICPU(address(this)).calculateMove(ctx, moveIndex, extraData); - bytes32 p1Salt = keccak256(abi.encode(battleKey, msg.sender, block.timestamp)); + (uint128 cpuMoveIndex, uint16 cpuExtraData) = ICPU(address(this)).calculateMove(ctx, moveIndex, extraData); + // Salt narrows to 104 bits to match the engine's storage; ample for an unpredictable + // RNG source within the seconds-to-minutes commit-reveal window. + uint104 p1Salt = uint104(uint256(keccak256(abi.encode(battleKey, msg.sender, block.timestamp)))); if (playerSwitchForTurnFlag == 1) { ENGINE.executeWithSingleMove(battleKey, uint8(cpuMoveIndex), p1Salt, cpuExtraData); diff --git a/src/cpu/ICPU.sol b/src/cpu/ICPU.sol index 01e1b381..49e6c1c3 100644 --- a/src/cpu/ICPU.sol +++ b/src/cpu/ICPU.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import {CPUContext, ProposedBattle} from "../Structs.sol"; interface ICPU { - function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint240 playerExtraData) + function calculateMove(CPUContext memory ctx, uint8 playerMoveIndex, uint16 playerExtraData) external - returns (uint128 moveIndex, uint240 extraData); + returns (uint128 moveIndex, uint16 extraData); function startBattle(ProposedBattle memory proposal) external returns (bytes32 battleKey); } diff --git a/src/cpu/OkayCPU.sol b/src/cpu/OkayCPU.sol index 0b38edd4..c5eccddb 100644 --- a/src/cpu/OkayCPU.sol +++ b/src/cpu/OkayCPU.sol @@ -21,10 +21,10 @@ contract OkayCPU is CPU { /** * If it's turn 0, swap in a mon that resists the other player's type1 (if possible) */ - function calculateMove(CPUContext memory ctx, uint8, uint240) + function calculateMove(CPUContext memory ctx, uint8, uint16) external override - returns (uint128 moveIndex, uint240 extraData) + returns (uint128 moveIndex, uint16 extraData) { (RevealedMove[] memory noOp, RevealedMove[] memory moves, RevealedMove[] memory switches) = _calculateValidMoves(ctx); @@ -126,7 +126,7 @@ contract OkayCPU is CPU { RevealedMove[] memory noOp, RevealedMove[] memory moves, RevealedMove[] memory switches - ) internal returns (uint128, uint240) { + ) internal returns (uint128, uint16) { // Single RNG call - use different bit ranges for different random decisions uint256 rng = _getRNG(battleKey); uint256 movesLen = moves.length; diff --git a/src/cpu/PlayerCPU.sol b/src/cpu/PlayerCPU.sol index 9cb710e4..7c0712e4 100644 --- a/src/cpu/PlayerCPU.sol +++ b/src/cpu/PlayerCPU.sol @@ -13,21 +13,21 @@ contract PlayerCPU is CPU { constructor(uint256 numMoves, IEngine engine, ICPURNG rng) CPU(numMoves, engine, rng) {} - function setMove(bytes32 battleKey, uint8 moveIndex, uint240 extraData) external { + function setMove(bytes32 battleKey, uint8 moveIndex, uint16 extraData) external { if (msg.sender != ENGINE.getPlayersForBattle(battleKey)[0]) { revert NotP0(); } - declaredMoveForBattle[battleKey] = RevealedMove({moveIndex: moveIndex, salt: "", extraData: extraData}); + declaredMoveForBattle[battleKey] = RevealedMove({moveIndex: moveIndex, salt: 0, extraData: extraData}); } /** * Returns the move that p0 declared for this CPU, ignoring the rest of the context. */ - function calculateMove(CPUContext memory ctx, uint8, uint240) + function calculateMove(CPUContext memory ctx, uint8, uint16) external view override - returns (uint128 moveIndex, uint240 extraData) + returns (uint128 moveIndex, uint16 extraData) { return (declaredMoveForBattle[ctx.battleKey].moveIndex, declaredMoveForBattle[ctx.battleKey].extraData); } diff --git a/src/cpu/RandomCPU.sol b/src/cpu/RandomCPU.sol index 83f37d4c..0627d40d 100644 --- a/src/cpu/RandomCPU.sol +++ b/src/cpu/RandomCPU.sol @@ -15,10 +15,10 @@ contract RandomCPU is CPU { * If it's turn 0, randomly selects a mon index to swap to * Otherwise, randomly selects a valid move, switch index, or no op */ - function calculateMove(CPUContext memory ctx, uint8, uint240) + function calculateMove(CPUContext memory ctx, uint8, uint16) external override - returns (uint128 moveIndex, uint240 extraData) + returns (uint128 moveIndex, uint16 extraData) { (RevealedMove[] memory noOp, RevealedMove[] memory moves, RevealedMove[] memory switches) = _calculateValidMoves(ctx); diff --git a/src/effects/status/SleepStatus.sol b/src/effects/status/SleepStatus.sol index 564ae40a..a7e679da 100644 --- a/src/effects/status/SleepStatus.sol +++ b/src/effects/status/SleepStatus.sol @@ -41,7 +41,7 @@ contract SleepStatus is StatusEffect { MoveDecision memory moveDecision = engine.getMoveDecisionForBattleState(battleKey, targetIndex); uint8 moveIndex = moveDecision.packedMoveIndex & MOVE_INDEX_MASK; if (moveIndex != SWITCH_MOVE_INDEX) { - engine.setMove(battleKey, targetIndex, NO_OP_MOVE_INDEX, "", 0); + engine.setMove(battleKey, targetIndex, NO_OP_MOVE_INDEX, 0, 0); } } diff --git a/src/lib/ValidatorLogic.sol b/src/lib/ValidatorLogic.sol index 172229fb..060d9be2 100644 --- a/src/lib/ValidatorLogic.sol +++ b/src/lib/ValidatorLogic.sol @@ -43,7 +43,7 @@ library ValidatorLogic { uint256 rawMoveSlot, uint256 playerIndex, uint256 activeMonIndex, - uint240 extraData, + uint16 extraData, uint32 baseStamina, int32 staminaDelta ) internal view returns (bool valid) { diff --git a/src/mons/aurox/BullRush.sol b/src/mons/aurox/BullRush.sol index 7902cee2..21e747e6 100644 --- a/src/mons/aurox/BullRush.sol +++ b/src/mons/aurox/BullRush.sol @@ -40,7 +40,7 @@ contract BullRush is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) public override { // Deal the damage to opponent diff --git a/src/mons/aurox/GildedRecovery.sol b/src/mons/aurox/GildedRecovery.sol index be90436a..66b939c1 100644 --- a/src/mons/aurox/GildedRecovery.sol +++ b/src/mons/aurox/GildedRecovery.sol @@ -24,10 +24,10 @@ contract GildedRecovery is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240 extraData, + uint16 extraData, uint256 ) external { - // extraData contains the mon index as raw uint240 + // extraData contains the mon index as raw uint16 uint256 targetMonIndex = uint256(extraData); // Check if the target mon has a status effect @@ -84,7 +84,7 @@ contract GildedRecovery is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/aurox/IronWall.sol b/src/mons/aurox/IronWall.sol index 397d3d6c..3c8d807f 100644 --- a/src/mons/aurox/IronWall.sol +++ b/src/mons/aurox/IronWall.sol @@ -25,7 +25,7 @@ contract IronWall is IMoveSet, BasicEffect { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Check to see if the effect is already active @@ -68,7 +68,7 @@ contract IronWall is IMoveSet, BasicEffect { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/aurox/VolatilePunch.sol b/src/mons/aurox/VolatilePunch.sol index fb288cad..772eaa2e 100644 --- a/src/mons/aurox/VolatilePunch.sol +++ b/src/mons/aurox/VolatilePunch.sol @@ -46,7 +46,7 @@ contract VolatilePunch is StandardAttack { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) public override { // Deal the damage to opponent diff --git a/src/mons/ekineki/BubbleBop.sol b/src/mons/ekineki/BubbleBop.sol index cb18cc3f..5aa35f92 100644 --- a/src/mons/ekineki/BubbleBop.sol +++ b/src/mons/ekineki/BubbleBop.sol @@ -39,7 +39,7 @@ contract BubbleBop is StandardAttack { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) public override { uint32 effectiveCritRate = NineNineNineLib._getEffectiveCritRate(engine, battleKey, attackerPlayerIndex); diff --git a/src/mons/ekineki/NineNineNine.sol b/src/mons/ekineki/NineNineNine.sol index 0c1a6f41..614311c5 100644 --- a/src/mons/ekineki/NineNineNine.sol +++ b/src/mons/ekineki/NineNineNine.sol @@ -17,7 +17,7 @@ contract NineNineNine is IMoveSet { return "Nine Nine Nine"; } - function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint240, uint256) external { + function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint16, uint256) external { // Set crit boost for the next turn uint256 currentTurn = engine.getTurnIdForBattleState(battleKey); uint64 key = NineNineNineLib._getKey(attackerPlayerIndex); @@ -40,7 +40,7 @@ contract NineNineNine is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/ekineki/Overflow.sol b/src/mons/ekineki/Overflow.sol index 7d3fa135..f75c87bd 100644 --- a/src/mons/ekineki/Overflow.sol +++ b/src/mons/ekineki/Overflow.sol @@ -39,7 +39,7 @@ contract Overflow is StandardAttack { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) public override { uint32 effectiveCritRate = NineNineNineLib._getEffectiveCritRate(engine, battleKey, attackerPlayerIndex); diff --git a/src/mons/ekineki/SneakAttack.sol b/src/mons/ekineki/SneakAttack.sol index 3c669924..2682e158 100644 --- a/src/mons/ekineki/SneakAttack.sol +++ b/src/mons/ekineki/SneakAttack.sol @@ -35,7 +35,7 @@ contract SneakAttack is IMoveSet, BasicEffect { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240 extraData, + uint16 extraData, uint256 rng ) external { // Check if already used this switch-in (effect present = already used) @@ -107,7 +107,7 @@ contract SneakAttack is IMoveSet, BasicEffect { return MoveClass.Special; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/embursa/HeatBeacon.sol b/src/mons/embursa/HeatBeacon.sol index b6d3f0e2..7d60ab69 100644 --- a/src/mons/embursa/HeatBeacon.sol +++ b/src/mons/embursa/HeatBeacon.sol @@ -28,7 +28,7 @@ contract HeatBeacon is IMoveSet { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 ) external { // Apply burn to opposing mon @@ -56,7 +56,7 @@ contract HeatBeacon is IMoveSet { return Type.Fire; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/embursa/HoneyBribe.sol b/src/mons/embursa/HoneyBribe.sol index a9a68614..653d4d05 100644 --- a/src/mons/embursa/HoneyBribe.sol +++ b/src/mons/embursa/HoneyBribe.sol @@ -51,7 +51,7 @@ contract HoneyBribe is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240, + uint16, uint256 ) external { // Heal active mon by max HP / 2**bribeLevel @@ -110,7 +110,7 @@ contract HoneyBribe is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/embursa/Q5.sol b/src/mons/embursa/Q5.sol index f6bf895a..fb5df4e0 100644 --- a/src/mons/embursa/Q5.sol +++ b/src/mons/embursa/Q5.sol @@ -36,7 +36,7 @@ contract Q5 is IMoveSet, BasicEffect { attackerPlayerIndex = uint256(data) & type(uint128).max; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256, uint16, uint256) external { // Add effect to global effects engine.addEffect(2, attackerPlayerIndex, this, _packExtraData(1, attackerPlayerIndex)); @@ -58,7 +58,7 @@ contract Q5 is IMoveSet, BasicEffect { return Type.Fire; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/embursa/SetAblaze.sol b/src/mons/embursa/SetAblaze.sol index af8ae952..36cdf255 100644 --- a/src/mons/embursa/SetAblaze.sol +++ b/src/mons/embursa/SetAblaze.sol @@ -40,7 +40,7 @@ contract SetAblaze is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 args, + uint16 args, uint256 rng ) public override { engine.dispatchStandardAttack( diff --git a/src/mons/ghouliath/EternalGrudge.sol b/src/mons/ghouliath/EternalGrudge.sol index ad78b202..adecae58 100644 --- a/src/mons/ghouliath/EternalGrudge.sol +++ b/src/mons/ghouliath/EternalGrudge.sol @@ -30,7 +30,7 @@ contract EternalGrudge is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240, + uint16, uint256 ) external { // Apply the debuff (50% debuff to both attack and special attack) @@ -69,7 +69,7 @@ contract EternalGrudge is IMoveSet { return Type.Yin; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/ghouliath/WitherAway.sol b/src/mons/ghouliath/WitherAway.sol index 8115f38c..d8094642 100644 --- a/src/mons/ghouliath/WitherAway.sol +++ b/src/mons/ghouliath/WitherAway.sol @@ -39,7 +39,7 @@ contract WitherAway is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage and inflict panic diff --git a/src/mons/gorillax/RockPull.sol b/src/mons/gorillax/RockPull.sol index 68457ad5..f86b3094 100644 --- a/src/mons/gorillax/RockPull.sol +++ b/src/mons/gorillax/RockPull.sol @@ -40,7 +40,7 @@ contract RockPull is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 rng ) external { if (_didOtherPlayerChooseSwitch(engine, battleKey, attackerPlayerIndex)) { @@ -98,7 +98,7 @@ contract RockPull is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/iblivion/Brightback.sol b/src/mons/iblivion/Brightback.sol index 46f42998..e9712c1c 100644 --- a/src/mons/iblivion/Brightback.sol +++ b/src/mons/iblivion/Brightback.sol @@ -41,7 +41,7 @@ contract Brightback is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 rng ) external { (int32 damageDealt,) = AttackCalculator._calculateDamage( @@ -95,7 +95,7 @@ contract Brightback is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/iblivion/Loop.sol b/src/mons/iblivion/Loop.sol index 8c1b4c2e..6b418083 100644 --- a/src/mons/iblivion/Loop.sol +++ b/src/mons/iblivion/Loop.sol @@ -70,7 +70,7 @@ contract Loop is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Check if Loop is already active @@ -134,7 +134,7 @@ contract Loop is IMoveSet { return Type.Yang; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/iblivion/Renormalize.sol b/src/mons/iblivion/Renormalize.sol index 656dd9f6..81ac7114 100644 --- a/src/mons/iblivion/Renormalize.sol +++ b/src/mons/iblivion/Renormalize.sol @@ -42,7 +42,7 @@ contract Renormalize is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Set Baselight level to 3 @@ -67,7 +67,7 @@ contract Renormalize is IMoveSet { return Type.Yang; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/iblivion/UnboundedStrike.sol b/src/mons/iblivion/UnboundedStrike.sol index 6225859e..f4a3d461 100644 --- a/src/mons/iblivion/UnboundedStrike.sol +++ b/src/mons/iblivion/UnboundedStrike.sol @@ -45,7 +45,7 @@ contract UnboundedStrike is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 rng ) external { uint256 baselightLevel = BASELIGHT.getBaselightLevel(engine, battleKey, attackerPlayerIndex, attackerMonIndex); @@ -95,7 +95,7 @@ contract UnboundedStrike is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/inutia/ChainExpansion.sol b/src/mons/inutia/ChainExpansion.sol index a462fc3f..7d673aad 100644 --- a/src/mons/inutia/ChainExpansion.sol +++ b/src/mons/inutia/ChainExpansion.sol @@ -33,7 +33,7 @@ contract ChainExpansion is IMoveSet, BasicEffect { return keccak256(abi.encode(playerIndex, monIndex, name())); } - function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint240, uint256) external { + function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint16, uint256) external { // Check if the ability is already applied globally (EffectInstance[] memory effects, ) = engine.getEffects(battleKey, 2, 2); for (uint256 i = 0; i < effects.length; i++) { @@ -61,7 +61,7 @@ contract ChainExpansion is IMoveSet, BasicEffect { return MoveClass.Other; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/inutia/HitAndDip.sol b/src/mons/inutia/HitAndDip.sol index 36357b77..dc087ec4 100644 --- a/src/mons/inutia/HitAndDip.sol +++ b/src/mons/inutia/HitAndDip.sol @@ -39,7 +39,7 @@ contract HitAndDip is StandardAttack { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage @@ -51,7 +51,7 @@ contract HitAndDip is StandardAttack { ); if (damage > 0) { - // extraData contains the swap index as raw uint240 + // extraData contains the swap index as raw uint16 uint256 swapIndex = uint256(extraData); engine.switchActiveMon(attackerPlayerIndex, swapIndex); } diff --git a/src/mons/inutia/Initialize.sol b/src/mons/inutia/Initialize.sol index 427147c0..d9fb1cfe 100644 --- a/src/mons/inutia/Initialize.sol +++ b/src/mons/inutia/Initialize.sol @@ -35,7 +35,7 @@ contract Initialize is IMoveSet, BasicEffect { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Check if global KV is set @@ -83,7 +83,7 @@ contract Initialize is IMoveSet, BasicEffect { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/malalien/TripleThink.sol b/src/mons/malalien/TripleThink.sol index 95a24830..5b0a8d0b 100644 --- a/src/mons/malalien/TripleThink.sol +++ b/src/mons/malalien/TripleThink.sol @@ -29,7 +29,7 @@ contract TripleThink is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Apply the buff @@ -58,7 +58,7 @@ contract TripleThink is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/pengym/Deadlift.sol b/src/mons/pengym/Deadlift.sol index 120974e0..065843f3 100644 --- a/src/mons/pengym/Deadlift.sol +++ b/src/mons/pengym/Deadlift.sol @@ -30,7 +30,7 @@ contract Deadlift is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { // Apply the buffs @@ -64,7 +64,7 @@ contract Deadlift is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/pengym/DeepFreeze.sol b/src/mons/pengym/DeepFreeze.sol index 6f841a39..9dba3bd8 100644 --- a/src/mons/pengym/DeepFreeze.sol +++ b/src/mons/pengym/DeepFreeze.sol @@ -47,7 +47,7 @@ contract DeepFreeze is IMoveSet { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) external { uint256 otherPlayerIndex = (attackerPlayerIndex + 1) % 2; @@ -90,7 +90,7 @@ contract DeepFreeze is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/pengym/PistolSquat.sol b/src/mons/pengym/PistolSquat.sol index 9bb24bee..b234624d 100644 --- a/src/mons/pengym/PistolSquat.sol +++ b/src/mons/pengym/PistolSquat.sol @@ -60,7 +60,7 @@ contract PistolSquat is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage diff --git a/src/mons/sofabbi/Gachachacha.sol b/src/mons/sofabbi/Gachachacha.sol index a25180f8..1d49a9bb 100644 --- a/src/mons/sofabbi/Gachachacha.sol +++ b/src/mons/sofabbi/Gachachacha.sol @@ -41,7 +41,7 @@ contract Gachachacha is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) external { uint256 chance = rng % OPP_KO_THRESHOLD_R; @@ -91,7 +91,7 @@ contract Gachachacha is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/sofabbi/GuestFeature.sol b/src/mons/sofabbi/GuestFeature.sol index 83fb7d6a..1b73f2f9 100644 --- a/src/mons/sofabbi/GuestFeature.sol +++ b/src/mons/sofabbi/GuestFeature.sol @@ -30,7 +30,7 @@ contract GuestFeature is IMoveSet { uint256 attackerPlayerIndex, uint256, uint256, - uint240 extraData, + uint16 extraData, uint256 rng ) external { uint256 monIndex = uint256(extraData); @@ -67,7 +67,7 @@ contract GuestFeature is IMoveSet { return MoveClass.Physical; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/sofabbi/SnackBreak.sol b/src/mons/sofabbi/SnackBreak.sol index ec40b197..7b78752b 100644 --- a/src/mons/sofabbi/SnackBreak.sol +++ b/src/mons/sofabbi/SnackBreak.sol @@ -42,7 +42,7 @@ contract SnackBreak is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { uint256 snackLevel = _getSnackLevel(engine, battleKey, attackerPlayerIndex, attackerMonIndex); @@ -78,7 +78,7 @@ contract SnackBreak is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/volthare/DualShock.sol b/src/mons/volthare/DualShock.sol index be91b0fc..bc541f89 100644 --- a/src/mons/volthare/DualShock.sol +++ b/src/mons/volthare/DualShock.sol @@ -45,7 +45,7 @@ contract DualShock is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage diff --git a/src/mons/volthare/MegaStarBlast.sol b/src/mons/volthare/MegaStarBlast.sol index 9ff0f9de..df7c0aa7 100644 --- a/src/mons/volthare/MegaStarBlast.sol +++ b/src/mons/volthare/MegaStarBlast.sol @@ -52,7 +52,7 @@ contract MegaStarBlast is IMoveSet { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) external { // Check if Overclock is active @@ -104,7 +104,7 @@ contract MegaStarBlast is IMoveSet { return MoveClass.Special; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/volthare/RoundTrip.sol b/src/mons/volthare/RoundTrip.sol index 8880e455..1fa154fe 100644 --- a/src/mons/volthare/RoundTrip.sol +++ b/src/mons/volthare/RoundTrip.sol @@ -39,7 +39,7 @@ contract RoundTrip is StandardAttack { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage @@ -51,7 +51,7 @@ contract RoundTrip is StandardAttack { ); if (damage > 0) { - // extraData contains the swap index as raw uint240 + // extraData contains the swap index as raw uint16 uint256 swapIndex = uint256(extraData); engine.switchActiveMon(attackerPlayerIndex, swapIndex); } diff --git a/src/mons/xmon/ContagiousSlumber.sol b/src/mons/xmon/ContagiousSlumber.sol index 5153ae73..5c349615 100644 --- a/src/mons/xmon/ContagiousSlumber.sol +++ b/src/mons/xmon/ContagiousSlumber.sol @@ -27,7 +27,7 @@ contract ContagiousSlumber is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240, + uint16, uint256 ) external { // Apply sleep to self @@ -54,7 +54,7 @@ contract ContagiousSlumber is IMoveSet { return MoveClass.Other; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/xmon/NightTerrors.sol b/src/mons/xmon/NightTerrors.sol index 399b053e..fb7984a7 100644 --- a/src/mons/xmon/NightTerrors.sol +++ b/src/mons/xmon/NightTerrors.sol @@ -36,7 +36,7 @@ contract NightTerrors is IMoveSet, BasicEffect { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256, - uint240, + uint16, uint256 ) external { uint256 defenderPlayerIndex = (attackerPlayerIndex + 1) % 2; @@ -96,7 +96,7 @@ contract NightTerrors is IMoveSet, BasicEffect { return MoveClass.Special; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/xmon/Somniphobia.sol b/src/mons/xmon/Somniphobia.sol index 7916a432..628e3553 100644 --- a/src/mons/xmon/Somniphobia.sol +++ b/src/mons/xmon/Somniphobia.sol @@ -18,7 +18,7 @@ contract Somniphobia is IMoveSet, BasicEffect { return "Somniphobia"; } - function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint240, uint256) external { + function move(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex, uint256, uint256, uint16, uint256) external { // Add effect globally for 6 turns (only if it's not already in global effects) (EffectInstance[] memory effects, ) = engine.getEffects(battleKey, 2, 2); for (uint256 i = 0; i < effects.length; i++) { @@ -45,7 +45,7 @@ contract Somniphobia is IMoveSet, BasicEffect { return MoveClass.Other; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/src/mons/xmon/VitalSiphon.sol b/src/mons/xmon/VitalSiphon.sol index d2f472d7..1f85f0d8 100644 --- a/src/mons/xmon/VitalSiphon.sol +++ b/src/mons/xmon/VitalSiphon.sol @@ -40,7 +40,7 @@ contract VitalSiphon is StandardAttack { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) public override { // Deal the damage diff --git a/src/moves/IMoveSet.sol b/src/moves/IMoveSet.sol index 3ca381fe..cba4b69b 100644 --- a/src/moves/IMoveSet.sol +++ b/src/moves/IMoveSet.sol @@ -13,7 +13,7 @@ interface IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) external; function priority(IEngine engine, bytes32 battleKey, uint256 attackerPlayerIndex) external view returns (uint32); @@ -22,7 +22,7 @@ interface IMoveSet { view returns (uint32); function moveType(IEngine engine, bytes32 battleKey) external view returns (Type); - function isValidTarget(IEngine engine, bytes32 battleKey, uint240 extraData) external view returns (bool); + function isValidTarget(IEngine engine, bytes32 battleKey, uint16 extraData) external view returns (bool); function moveClass(IEngine engine, bytes32 battleKey) external view returns (MoveClass); function extraDataType() external view returns (ExtraDataType); diff --git a/src/moves/StandardAttack.sol b/src/moves/StandardAttack.sol index 47bc9f51..66a464d6 100644 --- a/src/moves/StandardAttack.sol +++ b/src/moves/StandardAttack.sol @@ -51,7 +51,7 @@ contract StandardAttack is IMoveSet, Ownable { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240, + uint16, uint256 rng ) public virtual { _move(engine, battleKey, attackerPlayerIndex, defenderMonIndex, rng); @@ -83,7 +83,7 @@ contract StandardAttack is IMoveSet, Ownable { ); } - function isValidTarget(IEngine, bytes32, uint240) public pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) public pure returns (bool) { return true; } diff --git a/test/BattleHistoryTest.sol b/test/BattleHistoryTest.sol index 005af49a..2aed9ea2 100644 --- a/test/BattleHistoryTest.sol +++ b/test/BattleHistoryTest.sol @@ -166,10 +166,10 @@ contract BattleHistoryTest is Test, BattleHelper { address p1, uint8 p0MoveIndex, uint8 p1MoveIndex, - uint240 p0ExtraData, - uint240 p1ExtraData + uint16 p0ExtraData, + uint16 p1ExtraData ) internal { - bytes32 salt = ""; + uint104 salt = 0; bytes32 p0MoveHash = keccak256(abi.encodePacked(p0MoveIndex, salt, p0ExtraData)); bytes32 p1MoveHash = keccak256(abi.encodePacked(p1MoveIndex, salt, p1ExtraData)); @@ -199,7 +199,7 @@ contract BattleHistoryTest is Test, BattleHelper { // First move - both players switch to their mon _commitRevealExecute( - battleKey, battleData.p0, battleData.p1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + battleKey, battleData.p0, battleData.p1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Second move - both attack (faster mon wins) @@ -216,7 +216,7 @@ contract BattleHistoryTest is Test, BattleHelper { assertEq(battleHistory.getNumBattles(BOB), 0, "Bob should have 0 battles before completion"); // First turn - both switch to their mons - _commitRevealExecute(battleKey, ALICE, BOB, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecute(battleKey, ALICE, BOB, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Stats should still be 0 after first turn assertEq(battleHistory.getNumBattles(ALICE), 0, "Alice should have 0 battles after switch"); diff --git a/test/BetterCPUInlineGasTest.sol b/test/BetterCPUInlineGasTest.sol index 9cccd4e5..e7b4112e 100644 --- a/test/BetterCPUInlineGasTest.sol +++ b/test/BetterCPUInlineGasTest.sol @@ -159,28 +159,28 @@ contract BetterCPUInlineGasTest is Test { // Turn 0: lead selection. Both players "switch in" a starting mon. vm.startSnapshotGas("Turn0_Lead"); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); uint256 turn0Gas = vm.stopSnapshotGas("Turn0_Lead"); engine.resetCallContext(); // Turns 1-4: both attack with move 1. Every one is flag == 2, no KOs. vm.startSnapshotGas("Turn1_BothAttack"); - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); uint256 turn1Gas = vm.stopSnapshotGas("Turn1_BothAttack"); engine.resetCallContext(); vm.startSnapshotGas("Turn2_BothAttack"); - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); uint256 turn2Gas = vm.stopSnapshotGas("Turn2_BothAttack"); engine.resetCallContext(); vm.startSnapshotGas("Turn3_BothAttack"); - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); uint256 turn3Gas = vm.stopSnapshotGas("Turn3_BothAttack"); engine.resetCallContext(); vm.startSnapshotGas("Turn4_BothAttack"); - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); uint256 turn4Gas = vm.stopSnapshotGas("Turn4_BothAttack"); engine.resetCallContext(); @@ -225,11 +225,11 @@ contract BetterCPUInlineGasTest is Test { mockCPURNG.setRNG(0); // Turn 0: lead. - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: both attack. CPU's move 1 (BP=40, attack=200, defense=10) should KO Alice. - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); engine.resetCallContext(); // After the KO we should be in flag==0 (Alice forced switch). @@ -238,7 +238,7 @@ contract BetterCPUInlineGasTest is Test { // Measure the cheap-router path: Alice submits her switch via the CPU manager. vm.startSnapshotGas("Flag0_P0ForcedSwitch"); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1)); uint256 flag0Gas = vm.stopSnapshotGas("Flag0_P0ForcedSwitch"); engine.resetCallContext(); diff --git a/test/BetterCPUTest.sol b/test/BetterCPUTest.sol index e331a72a..5965ae46 100644 --- a/test/BetterCPUTest.sol +++ b/test/BetterCPUTest.sol @@ -198,13 +198,13 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Turn 0: Both select mon 0 - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Deal some damage to Alice's mon so CPU sees it can KO // The CPU should select the high power move (index 1) to secure the KO // Set RNG to not trigger random selection mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Check that Alice's mon took massive damage (from high power attack) int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); @@ -243,7 +243,7 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Alice selects mon 0 (Fire type) - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // CPU should have selected Liquid mon (index 1) uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); @@ -298,7 +298,7 @@ contract BetterCPUTest is Test { // Since neither mon resists Liquid (Alice's lead could be Liquid), CPU picks randomly // We force Fire mon to be selected mockCPURNG.setRNG(0); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Get active mons - CPU might have selected based on type calcs uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); @@ -306,7 +306,7 @@ contract BetterCPUTest is Test { // Turn 1: CPU should detect kill threat from Fire attack and switch to Liquid if currently Fire mockCPURNG.setRNG(1); // Don't trigger random selection - cpu.selectMove(battleKey, 0, "", 0); // Alice attacks + cpu.selectMove(battleKey, 0, uint104(0), 0); // Alice attacks // If CPU started with Fire, it should switch to Liquid to survive // If CPU started with Liquid, it should stay (already resists Fire) @@ -354,12 +354,12 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(team, team); // Turn 0: Both select mon 0 - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Use the expensive attack (costs 5 stamina) // RNG = 1 won't trigger random selection (1 % 10 != 0) mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // Stamina delta should be -5 int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -367,7 +367,7 @@ contract BetterCPUTest is Test { // Turn 2: Opponent rests (P4 path). New BetterCPU attacks on free turns even at low stamina. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Stamina should be -10 (attacked again with the 5-cost move on the free turn) staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -409,12 +409,12 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(team, team); // Turn 0: Both select mon 0 - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: At full HP, CPU should prefer setup move // Set RNG to not trigger random selection mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Check stamina consumed (setup move costs 1) int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -434,28 +434,34 @@ contract BetterCPUTest is Test { moves[1] = uint256(uint160(address(mediumAttack))); moves[2] = uint256(uint160(address(strongAttack))); - Mon memory mon = _createMon(Type.Fire, 100, 50, 10); - mon.moves = moves; + // CPU mon is faster than Alice's so attack ordering is deterministic regardless + // of the engine's RNG-based speed-tie breaker. + Mon memory aliceMon = _createMonWithSpeed(Type.Fire, 100, 50, 10, 10); + aliceMon.moves = moves; + Mon memory cpuMon = _createMonWithSpeed(Type.Fire, 100, 50, 10, 100); + cpuMon.moves = moves; - // Need 2 mons per team - Mon[] memory team = new Mon[](2); - team[0] = mon; - team[1] = mon; + Mon[] memory aliceTeam = new Mon[](2); + aliceTeam[0] = aliceMon; + aliceTeam[1] = aliceMon; + Mon[] memory cpuTeam = new Mon[](2); + cpuTeam[0] = cpuMon; + cpuTeam[1] = cpuMon; - bytes32 battleKey = _startBattleWithCPU(team, team); + bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Turn 0: Both select mon 0 - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU is at full HP, so attack first with Alice to damage CPU // Then CPU will be at non-full HP and prefer attack moves mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 2, "", 0); // Alice uses strong attack on CPU + cpu.selectMove(battleKey, 2, uint104(0), 0); // Alice uses strong attack on CPU // Now CPU's HP is damaged, next turn it should use highest damage move // Turn 2: CPU should select the strongest attack mockCPURNG.setRNG(1); // Don't trigger random - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Verify significant damage was dealt (strong attack) - Alice took damage both turns int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); @@ -492,7 +498,7 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Alice selects mon 0 (Fire/Nature) - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should select Liquid mon (resists both Fire and Nature)"); @@ -521,7 +527,7 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Fire, Type.Nature, 20); // 2x bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should select Fire mon (2x offensive vs Nature)"); @@ -546,7 +552,7 @@ contract BetterCPUTest is Test { } bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Just verify no crash and valid index uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); @@ -601,7 +607,7 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Turn 0: lead selection. All neutral → picks mon 0 (first). - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should lead with mon 0"); @@ -609,12 +615,12 @@ contract BetterCPUTest is Test { // Turn 1: Alice uses Fire move (move 0). All CPU mons take equal Fire damage. // P5 materiality fails. CPU stays. Mon0 KO'd. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // Turn 2 (forced switch): Alice signals move 1 (Liquid). CPU evaluates Liquid damage. // Mon2(Nature) resists Liquid → takes less damage → picked. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 1, "", 0); + cpu.selectMove(battleKey, 1, uint104(0), 0); engine.resetCallContext(); activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 2, "CPU should switch to Nature (resists Liquid attack)"); @@ -649,11 +655,11 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Turn 0: lead selection - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU should use KO move. Alice attacks weakly. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // Alice's mon should be KO'd int32 aliceKO = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.IsKnockedOut); @@ -680,11 +686,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = moves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Both attack. CPU outspeeds → KOs Alice first. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 aliceKO = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.IsKnockedOut); assertEq(aliceKO, 1, "CPU should KO Alice when outspeeding"); @@ -716,11 +722,11 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Fire, Type.Liquid, 5); // 0.5x bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU outsped and opponent can KO → CPU should switch to Liquid. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should switch to Liquid when outsped in KO race"); @@ -755,11 +761,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU should pick the cheaper KO move (cost=1). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // Stamina delta should be -1 (cheap move used) int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -792,11 +798,11 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Fire, Type.Nature, 20); // 2x bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice switches to mon 1 (Nature, hp=20). CPU should KO it. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); engine.resetCallContext(); // Alice's mon 1 should be KO'd int32 aliceMon1KO = engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.IsKnockedOut); @@ -837,11 +843,11 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Liquid, Type.Nature, 5); // 0.5x bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice switches to Nature mon. CPU should use Fire attack (best damage). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); engine.resetCallContext(); // Alice's Nature mon should take Fire damage (500) int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.Hp); @@ -873,11 +879,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice switches. CPU has no affordable moves → rests. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); engine.resetCallContext(); // CPU stamina should be unchanged (rested) int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -915,11 +921,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice rests. No KO possible (hp=500). CPU should use strongest move in P4. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDelta, -400, "CPU should use bp=80 move for 400 damage"); @@ -949,11 +955,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice rests. CPU has no affordable moves → also rests. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); assertEq(staminaDelta, 0, "CPU should rest when no affordable moves"); @@ -994,14 +1000,14 @@ contract BetterCPUTest is Test { bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); // Lead selection: Alice is Liquid type. Liquid→Metal=1x, Liquid→Liquid=1x. Neutral. Mon0 leads. - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should lead with Mon0 (Metal)"); // Turn 1: Alice uses Fire attack. Lethal to Metal. CPU switches to Liquid. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should switch to Liquid to survive lethal Fire attack"); @@ -1027,11 +1033,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = moves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice attacks weakly. CPU stays and attacks back. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should stay when damage is low"); @@ -1056,10 +1062,11 @@ contract BetterCPUTest is Test { uint256[] memory moves = new uint256[](1); moves[0] = uint256(uint160(address(strongAttack))); + // CPU mons are faster so they attack first and get to deal damage before being KO'd. Mon[] memory cpuTeam = new Mon[](2); - cpuTeam[0] = _createMon(Type.Fire, 100, 50, 10); + cpuTeam[0] = _createMonWithSpeed(Type.Fire, 100, 50, 10, 100); cpuTeam[0].moves = moves; - cpuTeam[1] = _createMon(Type.Fire, 100, 50, 10); + cpuTeam[1] = _createMonWithSpeed(Type.Fire, 100, 50, 10, 100); cpuTeam[1].moves = moves; Mon[] memory aliceTeam = new Mon[](2); @@ -1069,11 +1076,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = moves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Both lethal, no material improvement → CPU stays and attacks. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // CPU should have stayed (attacked, not switched) int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); @@ -1111,14 +1118,14 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Fire, Type.Liquid, 5); // 0.5x bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should lead with Mon0"); // Turn 1: Alice Fire attack → lethal to Metal, Liquid survives → switch. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should switch to Liquid (materially better)"); @@ -1148,11 +1155,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice uses Self move. CPU skips P5, attacks in P6. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 0, "CPU should stay when opponent uses Self move"); @@ -1196,11 +1203,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice attacks weakly. CPU uses best move in P6. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDelta, -400, "CPU should use bp=80 for 400 damage"); @@ -1237,11 +1244,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU should pick cheaper move (cost=1). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); assertEq(staminaDelta, -1, "CPU should pick cheaper move within damage threshold"); @@ -1278,11 +1285,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU should pick bp=100 (cost=3) since bp=50 is outside threshold. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); assertEq(staminaDelta, -3, "CPU should pick strongest move when cheap one is outside threshold"); @@ -1314,11 +1321,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU can't afford moves → rests. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); assertEq(staminaDelta, 0, "CPU should rest when no affordable moves"); @@ -1349,11 +1356,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU exhausted, switches to Mon1. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should switch when exhausted and switch available"); @@ -1397,12 +1404,12 @@ contract BetterCPUTest is Test { // Set preferred move: monIndex=0, key=CONFIG_PREFERRED_MOVE(0), value=2 (moveIndex 1 + 1) cpu.setMonConfig(0, 0, 2); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU should use preferred move (bp=90). Damage = 90*50/10 = 450. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDelta, -450, "CPU should use preferred move (bp=90) within threshold"); @@ -1444,12 +1451,12 @@ contract BetterCPUTest is Test { // Set preferred move: monIndex=0, key=CONFIG_PREFERRED_MOVE(0), value=2 (moveIndex 1 + 1) cpu.setMonConfig(0, 0, 2); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Preferred too weak → CPU uses bp=100. Damage = 100*50/10 = 500. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDelta, -500, "CPU should ignore preferred move when too weak"); @@ -1491,19 +1498,19 @@ contract BetterCPUTest is Test { // Set switch-in move: monIndex=0, key=CONFIG_SWITCH_IN_MOVE(1), value=2 (moveIndex 1 + 1) cpu.setMonConfig(0, 1, 2); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice rests (P4 safe turn). CPU uses switch-in move (Self, bp=0). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDeltaTurn1 = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDeltaTurn1, 0, "Turn 1: CPU should use Self switch-in move (no damage)"); // Turn 2: Alice rests again. Switch-in move already used → normal P4 (best damage). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDeltaTurn2 = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDeltaTurn2, -250, "Turn 2: CPU should use attack move (damage 250)"); @@ -1545,19 +1552,19 @@ contract BetterCPUTest is Test { // Set switch-in move for Mon0 cpu.setMonConfig(0, 1, 2); // moveIndex 1 + 1 - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Alice rests. CPU uses switch-in Self move. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); int32 aliceHpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); assertEq(aliceHpDelta, 0, "Turn 1: switch-in Self move fires (no damage)"); // Turn 2: Alice rests. CPU attacks normally (switch-in already used). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Turn 3: Alice switches to mon 1. CPU re-evaluates. // On the switch turn, the CPU gets the switch-in move bit cleared for Mon0 when switching. @@ -1597,11 +1604,11 @@ contract BetterCPUTest is Test { typeCalc.setTypeEffectiveness(Type.Fire, Type.Liquid, 5); // 0.5x so Liquid is a viable switch bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: Both can KO. Speed tie → _weGoFirst returns false → CPU should switch. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); assertEq(activeIndex[1], 1, "CPU should switch on speed tie (play it safe)"); @@ -1631,11 +1638,11 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU priority 5 > Alice priority 1 → CPU goes first, KOs Alice. mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 aliceKO = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.IsKnockedOut); assertEq(aliceKO, 1, "CPU should KO Alice with higher priority move"); @@ -1670,7 +1677,7 @@ contract BetterCPUTest is Test { aliceTeam[1].moves = aliceMoves; bytes32 battleKey = _startBattleWithCPU(aliceTeam, cpuTeam); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1: CPU can't afford moves. Has switch option but P5 won't trigger (10 damage = 5%). // Falls through to P6: no moves. Switch available → might switch. @@ -1680,7 +1687,7 @@ contract BetterCPUTest is Test { // To force no-op, make team size 1? Can't, validator requires >= 2 for MONS_PER_TEAM. // Alternative: test that stamina is unchanged (CPU didn't attack). mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); assertEq(staminaDelta, 0, "CPU stamina should be unchanged (couldn't afford attack)"); diff --git a/test/CPUTest.sol b/test/CPUTest.sol index 6cfaffd3..3b20acba 100644 --- a/test/CPUTest.sol +++ b/test/CPUTest.sol @@ -217,7 +217,7 @@ contract CPUTest is Test { // Alice selects mon 2, CPU selects mon 1 mockCPURNG.setRNG(1); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(2)); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(2)); engine.resetCallContext(); // Assert active mon index for both p0 and p1 are correct assertEq(engine.getActiveMonIndexForBattleState(battleKey)[0], 2); @@ -232,7 +232,7 @@ contract CPUTest is Test { // Alice KO's the CPU's mon, the CPU chooses no op mockCPURNG.setRNG(0); // [no op, move 1, move 2, swap 0, swap 2, swap 3] and we want no op at index 0 - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); engine.resetCallContext(); // Check that the CPU now has 3 moves, all of which are switching to mon index 0, 2, or 3 { @@ -250,7 +250,7 @@ contract CPUTest is Test { } // Alice chooses no op (choice is irrelevant here), CPU chooses to switch to mon index 0 - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert the CPU now has mon index 0 as the active mon assertEq(engine.getActiveMonIndexForBattleState(battleKey)[1], 0); @@ -266,7 +266,7 @@ contract CPUTest is Test { mockCPURNG.setRNG(2); // [no op, move 1, move 2, swap 2, swap 3] and we want move 2 at index 2 // (note that the swaps are 0-indexed, and the moves are 1-indexed to refer to the above variable // naming convention, sorry D: ) - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert that there are now 3 moves, switching to mon index 2, 3, and no op (all stamina has been consumed) { @@ -277,7 +277,7 @@ contract CPUTest is Test { // Alice chooses no op, CPU chooses swapping to mon index 3 mockCPURNG.setRNG(2); // [no op, swap 2, swap 3] and we want swap 3 at index 2 - cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert the CPU now has mon index 3 as the active mon assertEq(engine.getActiveMonIndexForBattleState(battleKey)[1], 3); @@ -370,15 +370,15 @@ contract CPUTest is Test { // Verify that calculateMove returns the correct move CPUContext memory cpuCtx = engine.getCPUContext(battleKey); - (uint128 moveIndex, uint240 extraData) = playerCPU.calculateMove(cpuCtx, 0, 0); + (uint128 moveIndex, uint16 extraData) = playerCPU.calculateMove(cpuCtx, 0, 0); assertEq(moveIndex, 0); assertEq(extraData, 0); // Execute the turn - playerCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1)); + playerCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1)); engine.resetCallContext(); // Second turn: p0 sets move 1 for PlayerCPU (should override previous move) - playerCPU.setMove(battleKey, 1, uint240(42)); + playerCPU.setMove(battleKey, 1, uint16(42)); // Verify that calculateMove now returns the new move cpuCtx = engine.getCPUContext(battleKey); @@ -387,7 +387,7 @@ contract CPUTest is Test { assertEq(uint256(extraData), 42); // Execute another turn to verify the flow continues to work - playerCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + playerCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); } @@ -455,7 +455,7 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Player switches in mon index 0 (Fire type) - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Get active index for battle, it should be the resisted mon uint256[] memory activeIndex = engine.getActiveMonIndexForBattleState(battleKey); @@ -506,11 +506,11 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Turn 0, both player send in mon index 0 - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1, player rests, CPU should select no op because the move costs too much stamina mockCPURNG.setRNG(1); - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); } @@ -559,17 +559,17 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Turn 0, both player send in mon index 0 - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1, player rests, CPU should select move index 0 mockCPURNG.setRNG(1); // This triggers the OkayCPU to select a move, which should set its stamina delta to be -3 - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert the stamina delta for P1's active mon is -3 assertEq(engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina), -3); // Turn 2, player rests, CPU should rest as well - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert the stamina delta for P1's active mon is still -3 (it didn't go down more) assertEq(engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina), -3); @@ -621,10 +621,10 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Turn 0, both player send in mon index 0 - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1, p0 rests, CPU should select move index 1 (self move) - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert that the stamina delta is -1 for p1's active mon int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -678,10 +678,10 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Turn 0, both player send in mon index 0 - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1, p0 rests, CPU should select move index 1 (self move) - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert that the stamina delta is -1 for p1's active mon int32 staminaDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina); @@ -735,14 +735,14 @@ contract CPUTest is Test { bytes32 battleKey = okayCPU.startBattle(proposal); // Turn 0, both player send in mon index 0 - okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0)); + okayCPU.selectMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0)); engine.resetCallContext(); // Turn 1, set RNG to trigger smart random select and pick move index 1 // RNG needs: (RNG % 6 == 5) to trigger smart random, (RNG % 3 != 0) to not switch, ((RNG >> 8) % 2 == 1) to pick move 1 // 257 satisfies all: 257 % 6 = 5, 257 % 3 = 2, (257 >> 8) = 1 // So both mons should take 1 damage, as p0 also selects the damage move mockCPURNG.setRNG(257); - okayCPU.selectMove(battleKey, 1, "", 0); + okayCPU.selectMove(battleKey, 1, uint104(0), 0); engine.resetCallContext(); // Assert that the hp delta is -1 for p0's active mon and p1's active mon int32 hpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); @@ -753,7 +753,7 @@ contract CPUTest is Test { // Turn 2, set RNG to be 0 (do not trigger short circuit) // CPU should select no-op because no type advantage is currently set mockCPURNG.setRNG(0); - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert that the hp delta is still -1 for p0's active mon hpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); @@ -763,7 +763,7 @@ contract CPUTest is Test { typeCalc.setTypeEffectiveness(Type.Liquid, Type.Liquid, 2); // Now the CPU should select the damage move (move index 1) because it has a type advantage - okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, "", 0); + okayCPU.selectMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0); engine.resetCallContext(); // Assert that the hp delta is -2 for p0's active mon hpDelta = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Hp); diff --git a/test/DefaultCommitManagerTest.sol b/test/DefaultCommitManagerTest.sol index 8ba783fe..b3da8de8 100644 --- a/test/DefaultCommitManagerTest.sol +++ b/test/DefaultCommitManagerTest.sol @@ -85,19 +85,19 @@ contract DefaultCommitManagerTest is Test, BattleHelper { // Alice commits vm.startPrank(ALICE); uint8 moveIndex = SWITCH_MOVE_INDEX; - bytes32 moveHash = keccak256(abi.encodePacked(moveIndex, bytes32(""), uint240(0))); + bytes32 moveHash = keccak256(abi.encodePacked(moveIndex, uint104(0), uint16(0))); commitManager.commitMove(battleKey, moveHash); // Alice tries to reveal vm.expectRevert(DefaultCommitManager.NotYetRevealed.selector); - commitManager.revealMove(battleKey, moveIndex, bytes32(""), uint240(0), false); + commitManager.revealMove(battleKey, moveIndex, uint104(0), uint16(0), false); } function test_RevealBeforeSelfCommit() public { bytes32 battleKey = _startBattle(validator, engine, defaultOracle, defaultRegistry, matchmaker, address(commitManager)); // Alice sets commitment _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob sets commitment _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, 0, 0); @@ -108,13 +108,13 @@ contract DefaultCommitManagerTest is Test, BattleHelper { // Alice's turn again to move vm.startPrank(ALICE); vm.expectRevert(DefaultCommitManager.RevealBeforeSelfCommit.selector); - commitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, bytes32(""), 0, false); + commitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0, false); } function test_BattleNotYetStarted() public { vm.startPrank(ALICE); vm.expectRevert(DefaultCommitManager.BattleNotYetStarted.selector); - commitManager.revealMove(bytes32(0), NO_OP_MOVE_INDEX, bytes32(""), 0, false); + commitManager.revealMove(bytes32(0), NO_OP_MOVE_INDEX, uint104(0), 0, false); vm.startPrank(BOB); vm.expectRevert(DefaultCommitManager.BattleNotYetStarted.selector); commitManager.commitMove(bytes32(0), bytes32(0)); @@ -127,7 +127,7 @@ contract DefaultCommitManagerTest is Test, BattleHelper { engine.end(battleKey); vm.startPrank(ALICE); vm.expectRevert(DefaultCommitManager.BattleAlreadyComplete.selector); - commitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, bytes32(""), 0, false); + commitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0, false); vm.startPrank(BOB); vm.expectRevert(DefaultCommitManager.BattleAlreadyComplete.selector); commitManager.commitMove(battleKey, bytes32(0)); @@ -157,7 +157,7 @@ contract DefaultCommitManagerTest is Test, BattleHelper { vm.startPrank(ALICE); commitManager.commitMove(battleKey, bytes32("1")); vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(""), uint240(0), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(0), false); vm.warp(TIMEOUT * validator.PREV_TURN_MULTIPLIER() + 1); engine.end(battleKey); assertEq(engine.getWinner(battleKey), BOB); diff --git a/test/EngineGasTest.sol b/test/EngineGasTest.sol index c80bd59a..1dae1d6e 100644 --- a/test/EngineGasTest.sol +++ b/test/EngineGasTest.sol @@ -49,11 +49,6 @@ contract EngineGasTest is Test, BattleHelper { TestTeamRegistry defaultRegistry; DefaultMatchmaker matchmaker; - // Helper to pack StatBoostsMove extraData: lower 60 bits = playerIndex, next 60 bits = monIndex, next 60 bits = statIndex, upper 60 bits = boostAmount - function _packStatBoost(uint256 playerIndex, uint256 monIndex, uint256 statIndex, int32 boostAmount) internal pure returns (uint240) { - return uint240(playerIndex | (monIndex << 60) | (statIndex << 120) | (uint256(uint32(boostAmount)) << 180)); - } - function setUp() public { defaultOracle = new DefaultRandomnessOracle(); engine = new Engine(0, 0, 0); @@ -142,16 +137,16 @@ contract EngineGasTest is Test, BattleHelper { // - Alice swaps in mon index 3 // - Alice rests, Bob KOs vm.startSnapshotGas("FirstBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Alice uses burn, Bob uses frostbite _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 1, 0, 0); // Bob is mon index 0, we boost attack by 90% - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); // Alice is now mon index 1, Bob is mon index 0 _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); // Alice swaps in mon index 0 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0), true); engine.resetCallContext(); // Alice is now mon index 0, Bob rests _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); @@ -159,7 +154,7 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 3, NO_OP_MOVE_INDEX, 0, 0); // Bob sends in mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice rests, Bob uses self-stat boost _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); @@ -167,13 +162,13 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); // Alice swaps in mon index 2 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); // Alice rests, Bob KOs _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); // Alice swaps in mon index 3 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); // Alice rests, Bob KOs _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); @@ -223,24 +218,24 @@ contract EngineGasTest is Test, BattleHelper { // - Both players send in mon 0 vm.startSnapshotGas("SecondBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // - Alice sets up self-stat boost (move 3), Bob sets up Burn (move 1) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, 1, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); // - Alice KOs Bob (move 0 = damage) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); // - Bob swaps in mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // - Alice swaps in mon index 1, Bob sets up Frostbite (move 2) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, 2, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, 2, uint16(1), 0); // - Alice sets up self-stat boost (move 3, playerIndex=0, monIndex=1), Bob rests _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, NO_OP_MOVE_INDEX, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); // - Alice KOs Bob (move 0) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); // - Bob sends in mon index 2 vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); // - Alice rests, Bob uses self-stat boost (move 3, playerIndex=1, monIndex=2) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, NO_OP_MOVE_INDEX, 3, 0, _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); @@ -248,7 +243,7 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, NO_OP_MOVE_INDEX, 0, 0, 0); // - Alice swaps in mon index 2 vm.startPrank(ALICE); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); // - Alice uses self-stat boost (move 3, p0 mon2), Bob uses self-stat boost (move 3, p1 mon2) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, 3, _packStatBoost(0, 2, uint256(MonStateIndexName.Attack), int32(90)), _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); @@ -256,7 +251,7 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); // - Bob sends in mon index 3 vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); // - Alice KOs Bob (move 0) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); @@ -283,16 +278,16 @@ contract EngineGasTest is Test, BattleHelper { // Battle 3: Exact same sequence as Battle 1 vm.startSnapshotGas("ThirdBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Alice uses burn, Bob uses frostbite _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 0, 1, 0, 0); // Bob is mon index 0, we boost attack by 90% - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); // Alice is now mon index 1, Bob is mon index 0 _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); // Alice swaps in mon index 0 vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(0), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(0), true); engine.resetCallContext(); // Alice is now mon index 0, Bob rests _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); @@ -300,7 +295,7 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 3, NO_OP_MOVE_INDEX, 0, 0); // Bob sends in mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice rests, Bob uses self-stat boost _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); @@ -308,13 +303,13 @@ contract EngineGasTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); // Alice swaps in mon index 2 vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); // Alice rests, Bob KOs _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); // Alice swaps in mon index 3 vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); // Alice rests, Bob KOs _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); @@ -390,7 +385,7 @@ contract EngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Battle1_Execute"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); // Both switch in mon 0 + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Both switch in mon 0 _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey1, 0, 0, 0, 0); // Both attack - one dies // After this, battle should end uint256 execute1 = vm.stopSnapshotGas("Battle1_Execute"); @@ -404,7 +399,7 @@ contract EngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Battle2_Execute"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); // Both switch in mon 0 + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Both switch in mon 0 _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, 0, 0, 0); // Both attack - one dies uint256 execute2 = vm.stopSnapshotGas("Battle2_Execute"); @@ -469,7 +464,7 @@ contract EngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("B1_Execute"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Check after switch (BattleConfigView memory cfgAfterSwitch,) = engine.getBattle(battleKey1); @@ -510,7 +505,7 @@ contract EngineGasTest is Test, BattleHelper { console.log("After B2 setup - packedP1EffectsCount:", cfg2.packedP1EffectsCount); vm.startSnapshotGas("B2_Execute"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Both apply effect to each other (adds 2 effects - should REUSE slots) _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, 0, 0, 0); // Both attack - KO @@ -582,7 +577,7 @@ contract EngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("External_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, externalBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, externalBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, externalBattleKey, 0, 0, 0, 0); uint256 externalExecute = vm.stopSnapshotGas("External_Execute"); @@ -603,7 +598,7 @@ contract EngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Inline_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, inlineBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, inlineBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, inlineBattleKey, 0, 0, 0, 0); uint256 inlineExecute = vm.stopSnapshotGas("Inline_Execute"); @@ -664,7 +659,7 @@ contract EngineGasTest is Test, BattleHelper { new IEngineHook[](0), simpleRuleset, address(commitManager) ); vm.warp(vm.getBlockTimestamp() + 1); - _commitRevealExecuteForEngine(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(engine, commitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(engine, commitManager, battleKey1, 0, 0, 0, 0); // Get final HP deltas @@ -684,7 +679,7 @@ contract EngineGasTest is Test, BattleHelper { new IEngineHook[](0), inlineRuleset, address(inlineCM) ); vm.warp(vm.getBlockTimestamp() + 1); - _commitRevealExecuteForEngine(inlineEngine, inlineCM, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCM, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCM, battleKey2, 0, 0, 0, 0); // Get final HP deltas @@ -756,10 +751,10 @@ contract EngineGasTest is Test, BattleHelper { bytes32 battleKey, uint8 aliceMoveIndex, uint8 bobMoveIndex, - uint240 aliceExtraData, - uint240 bobExtraData + uint16 aliceExtraData, + uint16 bobExtraData ) internal { - bytes32 salt = ""; + uint104 salt = 0; bytes32 aliceMoveHash = keccak256(abi.encodePacked(aliceMoveIndex, salt, aliceExtraData)); bytes32 bobMoveHash = keccak256(abi.encodePacked(bobMoveIndex, salt, bobExtraData)); uint256 turnId = eng.getTurnIdForBattleState(battleKey); diff --git a/test/EngineGlobalKVTest.sol b/test/EngineGlobalKVTest.sol index f3d42257..7b1f7990 100644 --- a/test/EngineGlobalKVTest.sol +++ b/test/EngineGlobalKVTest.sol @@ -30,12 +30,12 @@ contract EngineGlobalKVTest is Test, BattleHelper { DefaultValidator validator; // Arbitrary keys used throughout the tests. - uint240 constant KEY_A = 1001; - uint240 constant KEY_B = 1002; - uint240 constant KEY_C = 1003; - uint240 constant KEY_D = 1004; - uint240 constant KEY_E = 1005; - uint240 constant KEY_F = 1006; + uint16 constant KEY_A = 1001; + uint16 constant KEY_B = 1002; + uint16 constant KEY_C = 1003; + uint16 constant KEY_D = 1004; + uint16 constant KEY_E = 1005; + uint16 constant KEY_F = 1006; function setUp() public { mockOracle = new MockRandomnessOracle(); @@ -71,7 +71,7 @@ contract EngineGlobalKVTest is Test, BattleHelper { defaultRegistry.setTeam(BOB, team); battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); } @@ -82,22 +82,22 @@ contract EngineGlobalKVTest is Test, BattleHelper { defaultRegistry.setTeam(BOB, team); battleKey2 = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); } /// @dev Both players use the mock write-move with their respective keys. - function _bothWrite(bytes32 battleKey, uint240 aliceKey, uint240 bobKey) internal { + function _bothWrite(bytes32 battleKey, uint16 aliceKey, uint16 bobKey) internal { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 0, aliceKey, bobKey); } /// @dev Alice writes; Bob rests. - function _aliceWrites(bytes32 battleKey, uint240 aliceKey) internal { + function _aliceWrites(bytes32 battleKey, uint16 aliceKey) internal { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, aliceKey, 0); } /// @dev Bob writes; Alice rests. - function _bobWrites(bytes32 battleKey, uint240 bobKey) internal { + function _bobWrites(bytes32 battleKey, uint16 bobKey) internal { _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 0, 0, bobKey); } @@ -127,7 +127,8 @@ contract EngineGlobalKVTest is Test, BattleHelper { bytes32 firstPacked = view1.globalKVEntries[0].value; // Second call re-writes via encoded value bump so we can confirm it changed. - uint240 extraData = KEY_A | (uint240(42) << 64); + // Layout: bits 0..9 = key, bits 10..15 = value. + uint16 extraData = KEY_A | (uint16(42) << 10); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, extraData, 0); (BattleConfigView memory view2,) = engine.getBattle(battleKey); diff --git a/test/EngineOptimizationTest.sol b/test/EngineOptimizationTest.sol index 943bdb22..607f235a 100644 --- a/test/EngineOptimizationTest.sol +++ b/test/EngineOptimizationTest.sol @@ -116,7 +116,7 @@ contract EngineOptimizationTest is Test, BattleHelper { // Switch in mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses effect move on Bob (Bob does NoOp) @@ -175,7 +175,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); @@ -248,7 +248,7 @@ contract EngineOptimizationTest is Test, BattleHelper { // Switch in mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both use 5-stamina move. After: -5 from move + 1 from RoundEnd regen = -4 @@ -318,7 +318,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both use 5-stamina move: staminaDelta = -5 + 1 (RoundEnd) = -4 @@ -393,7 +393,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Use 1-stamina move: -1 from move + 1 from RoundEnd regen = 0 (not +1) @@ -414,7 +414,7 @@ contract EngineOptimizationTest is Test, BattleHelper { _forceP1Switch(testEngine, signedManager, battleKey); - _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint240(1)); + _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint16(1)); uint256[] memory activeMons = testEngine.getActiveMonIndexForBattleState(battleKey); assertEq(activeMons[1], 1, "P1 should switch to mon 1"); @@ -433,7 +433,7 @@ contract EngineOptimizationTest is Test, BattleHelper { vm.startPrank(ALICE); vm.expectRevert(DefaultCommitManager.PlayerNotAllowed.selector); - signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(1)); + signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); vm.stopPrank(); } @@ -442,12 +442,12 @@ contract EngineOptimizationTest is Test, BattleHelper { _startSignedInlineSwitchBattle(false); _commitRevealExecuteForAliceAndBob( - testEngine, signedManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + testEngine, signedManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); vm.startPrank(BOB); vm.expectRevert(SignedCommitManager.NotSinglePlayerTurn.selector); - signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(1)); + signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); vm.stopPrank(); } @@ -456,11 +456,11 @@ contract EngineOptimizationTest is Test, BattleHelper { _startSignedInlineSwitchBattle(false); _forceP1Switch(testEngine, signedManager, battleKey); - _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint240(1)); + _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint16(1)); uint256 turnBefore = testEngine.getTurnIdForBattleState(battleKey); _commitRevealExecuteForAliceAndBob( - testEngine, signedManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + testEngine, signedManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); assertEq(testEngine.getTurnIdForBattleState(battleKey), turnBefore + 1, "Normal fallback should execute"); @@ -473,7 +473,7 @@ contract EngineOptimizationTest is Test, BattleHelper { _forceP1Switch(testEngine, signedManager, battleKey); vm.prank(BOB); - signedManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(1), true); + signedManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), true); testEngine.resetCallContext(); uint256[] memory activeMons = testEngine.getActiveMonIndexForBattleState(battleKey); @@ -489,11 +489,11 @@ contract EngineOptimizationTest is Test, BattleHelper { (Engine testEngine, SignedCommitManager signedManager, bytes32 battleKey) = _startSignedInlineSwitchBattle(true); _forceP1Switch(testEngine, signedManager, battleKey); - _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint240(1)); + _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, BOB, uint16(1)); assertEq(testEngine.getPlayerSwitchForTurnFlagForBattleState(battleKey), 0, "P0 should be forced to switch"); - _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, ALICE, uint240(1)); + _executeSinglePlayerMoveAndReset(testEngine, signedManager, battleKey, ALICE, uint16(1)); assertEq( testEngine.getPlayerSwitchForTurnFlagForBattleState(battleKey), 2, @@ -502,7 +502,7 @@ contract EngineOptimizationTest is Test, BattleHelper { uint256 turnBefore = testEngine.getTurnIdForBattleState(battleKey); _commitRevealExecuteForAliceAndBob( - testEngine, signedManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + testEngine, signedManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); assertEq( @@ -514,10 +514,10 @@ contract EngineOptimizationTest is Test, BattleHelper { function _forceP1Switch(Engine testEngine, SignedCommitManager signedManager, bytes32 battleKey) internal { _commitRevealExecuteForAliceAndBob( - testEngine, signedManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + testEngine, signedManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob( - testEngine, signedManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + testEngine, signedManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); assertEq(testEngine.getPlayerSwitchForTurnFlagForBattleState(battleKey), 1, "P1 should be forced to switch"); @@ -528,10 +528,10 @@ contract EngineOptimizationTest is Test, BattleHelper { SignedCommitManager signedManager, bytes32 battleKey, address player, - uint240 monIndex + uint16 monIndex ) internal { vm.prank(player); - signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), monIndex); + signedManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), monIndex); testEngine.resetCallContext(); } @@ -665,7 +665,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, warmupKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, warmupKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob(engine, commitManager, warmupKey, 0, 0, 0, 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, warmupKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, 0, 0); @@ -683,7 +683,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, externalKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, externalKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); vm.startSnapshotGas("ExternalStaminaRegen"); @@ -704,7 +704,7 @@ contract EngineOptimizationTest is Test, BattleHelper { ); vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, inlineKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, inlineKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); vm.startSnapshotGas("InlineStaminaRegen"); diff --git a/test/EngineTest.sol b/test/EngineTest.sol index 3579cdfa..7ff48a80 100644 --- a/test/EngineTest.sol +++ b/test/EngineTest.sol @@ -62,9 +62,9 @@ contract EngineTest is Test, BattleHelper { Mon dummyMon; IMoveSet dummyAttack; - // Helper to pack ForceSwitchMove extraData: lower 120 bits = playerIndex, upper 120 bits = monToSwitchIndex - function _packForceSwitch(uint256 playerIndex, uint256 monToSwitchIndex) internal pure returns (uint240) { - return uint240(playerIndex | (monToSwitchIndex << 120)); + // Pack ForceSwitchMove extraData: bit 0 = playerIndex (0/1), bits 1..15 = monToSwitchIndex + function _packForceSwitch(uint256 playerIndex, uint256 monToSwitchIndex) internal pure returns (uint16) { + return uint16((playerIndex & 0x1) | (monToSwitchIndex << 1)); } function setUp() public { @@ -123,7 +123,7 @@ contract EngineTest is Test, BattleHelper { // Let Alice and Bob both commit to switching _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob do a no-op @@ -190,7 +190,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -266,7 +266,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -348,7 +348,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -374,7 +374,7 @@ contract EngineTest is Test, BattleHelper { // Reveal Alice's move, and advance game state vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(""), uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), false); engine.execute(battleKey); engine.resetCallContext(); @@ -400,7 +400,7 @@ contract EngineTest is Test, BattleHelper { // Attempt to reveal Alice's move, and assert that we cannot advance the game state vm.startPrank(ALICE); vm.expectRevert(abi.encodeWithSignature("InvalidMove(address)", ALICE)); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(""), uint240(0), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(0), false); // Attempt to forcibly advance the game state vm.expectRevert(); @@ -476,7 +476,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -534,11 +534,11 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Second move, have Alice swap out to mon at index 1, have Bob use attack - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Assert that mon index for Alice is 1 // Assert that the mon state for Alice has -5 applied to the switched in mon @@ -587,11 +587,11 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Second move, have Alice swap out to mon at index 1, have Bob use fast attack - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Assert that mon index for Alice is 1 // Assert that the mon state for Alice has -5 applied to the previous mon @@ -640,11 +640,11 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Second move, have Alice swap out to mon at index 1, have Bob use fast attack which supersedes Switch - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Given that it's a KO (even though Alice chose switch), // check that now they have the priority flag again @@ -699,7 +699,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -752,7 +752,7 @@ contract EngineTest is Test, BattleHelper { // Select mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both attack (costs 1 stamina each) @@ -829,7 +829,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -900,19 +900,19 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, defaultOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Commit move index 0 for Bob uint8 moveIndex = 0; vm.startPrank(BOB); - bytes32 bobMoveHash = keccak256(abi.encodePacked(moveIndex, bytes32(""), uint240(0))); + bytes32 bobMoveHash = keccak256(abi.encodePacked(moveIndex, uint104(0), uint16(0))); commitManager.commitMove(battleKey, bobMoveHash); // Assert that Alice cannot reveal anything because of the stamina cost (she has the high stamina cost mon) vm.startPrank(ALICE); vm.expectRevert(abi.encodeWithSignature("InvalidMove(address)", ALICE)); - commitManager.revealMove(battleKey, moveIndex, bytes32(""), uint240(0), false); + commitManager.revealMove(battleKey, moveIndex, uint104(0), uint16(0), false); } // Ensure that we cannot write to mon state when there is no active execute() call in the call stack @@ -997,13 +997,13 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, which for Bob afflicts the instant death condition on the // opposing mon (Alice's) and knocks it out uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Assert Bob wins @@ -1076,20 +1076,20 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, which for Bob afflicts the instant death condition on the // opposing mon (Alice's) and knocks it out uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Now only Alice should be able to switch vm.startPrank(ALICE); // Alice should be able to reveal because she is the only player (player flag should be set) - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(""), uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), false); // Execute the switch engine.execute(battleKey); @@ -1135,13 +1135,13 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice swaps to mon index 1, and Bob applies the effect // The effect should be applied to mon index 1 for Alice but only during the duration of the turn // (We have a check for 2 instead of 1 to avoid confusing it with the base case state) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Assert that the temporary stat boost effect is updated to 2 because the roundEnd hook also runs assertEq(engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.Attack), 2); @@ -1209,14 +1209,14 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, which for Bob afflicts the instant death condition on the // opposing mon (Alice's) // But Alice's mon should KO Bob's before the end of round takes place uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Assert Alice wins @@ -1289,26 +1289,26 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, which for Bob afflicts the instant death condition on the // opposing mon (Alice's) and knocks it out // But Bob moves first (higher priority), so he gets the instant death affliction uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Now if Alice tries to pick a non-switch move, the engine should revert vm.startPrank(ALICE); - bytes32 salt = ""; + uint104 salt = 0; uint8 aliceMoveIndex = 0; bytes32 aliceMoveHash = keccak256(abi.encodePacked(aliceMoveIndex, salt, extraData)); commitManager.commitMove(battleKey, aliceMoveHash); // Bob reveals a swap vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint16(1), false); // Alice's reveal will revert (must choose switch) vm.startPrank(ALICE); @@ -1382,19 +1382,19 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, which for Bob afflicts the instant death condition on the // opposing mon (Alice's) and knocks it out // But Bob moves first (higher priority), so he gets the instant death affliction uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Now both moves have to swap to index 1 for their mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(1), uint240(1) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(1), uint16(1) ); } @@ -1456,7 +1456,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0 @@ -1464,7 +1464,7 @@ contract EngineTest is Test, BattleHelper { // Alice tries to go fast for a lethal effect // Bob should win priority and inflict skip turn effect uint8 moveIndex = 0; - uint240 extraData = 0; + uint16 extraData = 0; _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, moveIndex, moveIndex, extraData, extraData); // Assert no winner, and no damage dealt @@ -1538,7 +1538,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, but Alice encodes a swap to mon index 1 for player index 1 (Bob) @@ -1617,7 +1617,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both player pick move index 0, but Alice encodes a swap to mon index 1 for player index 0 (Alice) @@ -1696,12 +1696,12 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Bob commit and reveal to attack (move index 0) - uint240 extraData = 0; - bytes32 salt = ""; + uint16 extraData = 0; + uint104 salt = 0; uint8 moveIndex = 0; vm.startPrank(BOB); commitManager.commitMove(battleKey, keccak256(abi.encodePacked(moveIndex, salt, extraData))); @@ -1788,12 +1788,12 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Bob commit and reveal to attack (move index 0) - uint240 extraData = 0; - bytes32 salt = ""; + uint16 extraData = 0; + uint104 salt = 0; uint8 moveIndex = 0; vm.startPrank(BOB); commitManager.commitMove(battleKey, keccak256(abi.encodePacked(moveIndex, salt, extraData))); @@ -1885,7 +1885,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let both players select move index 0 @@ -1955,7 +1955,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // (Have Alice force Bob to switch to mon index 1, have Bob select the instant death switch in effect @@ -2024,12 +2024,12 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Have Alice switch to their second mon, have Bob select the instant death switch in effect // (But swapping to mon index 1 for Alice will trigger on switch in and kill the mon) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Assert that the player switch for turn flag is now 0, indicating Alice has to switch (, BattleData memory state) = engine.getBattle(battleKey); @@ -2099,7 +2099,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // After this, Alice's mon should be dead and Bob should be the winner @@ -2193,7 +2193,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice switches themselves to mon index 1, while Bob chooses move index 0 @@ -2293,11 +2293,11 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice switches themselves to mon index 1, while Bob chooses move index 0 - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Assert that Alice's new mon is now KOed assertEq(engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.IsKnockedOut), 1); @@ -2349,7 +2349,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks (they should apply the single instance effect on hit) @@ -2395,19 +2395,19 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob commits to NO_OP vm.startPrank(BOB); uint8 moveIndex = NO_OP_MOVE_INDEX; - bytes32 bobMoveHash = keccak256(abi.encodePacked(moveIndex, bytes32(""), uint240(0))); + bytes32 bobMoveHash = keccak256(abi.encodePacked(moveIndex, uint104(0), uint16(0))); commitManager.commitMove(battleKey, bobMoveHash); // Alice should revert when revealing vm.startPrank(ALICE); vm.expectRevert(abi.encodeWithSignature("InvalidMove(address)", ALICE)); - commitManager.revealMove(battleKey, 0, bytes32(""), uint240(0), false); + commitManager.revealMove(battleKey, 0, uint104(0), uint16(0), false); } function test_onMonSwitchOutHookWorksWithTempStatBoost() public { @@ -2451,7 +2451,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks (they should apply the temporary stat boost effect) @@ -2463,7 +2463,7 @@ contract EngineTest is Test, BattleHelper { // Alice and Bob both switch to mon index 1 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(1), uint240(1) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(1), uint16(1) ); // Assert that the temporary stat boost effect was removed from both mons @@ -2517,7 +2517,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks, both of them are move index 0 (do damage rebound) @@ -2568,8 +2568,8 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startBattle(twoMoveValidator, engine, defaultOracle, defaultRegistry, matchmaker, address(commitManager)); // Alice commits to swapping in mon index 1 - bytes32 salt = ""; - bytes32 aliceMoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(1))); + uint104 salt = 0; + bytes32 aliceMoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(1))); vm.startPrank(ALICE); commitManager.commitMove(battleKey, aliceMoveHash); @@ -2579,19 +2579,19 @@ contract EngineTest is Test, BattleHelper { // Bob reveals vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint16(1), false); // Bob cannot reveal twice vm.expectRevert(DefaultCommitManager.AlreadyRevealed.selector); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint16(1), false); // Alice reveals but does not execute vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint16(1), false); // Second reveal should also fail vm.expectRevert(DefaultCommitManager.AlreadyRevealed.selector); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint240(1), false); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, uint16(1), false); } function test_cannotCommitToEndedBattle() public { @@ -2622,7 +2622,7 @@ contract EngineTest is Test, BattleHelper { // Both players send in mon index 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob does nothing (it's his turn to move, so he'll lose by timeout) @@ -2671,7 +2671,7 @@ contract EngineTest is Test, BattleHelper { // Alice commits to switch to mon index 0 vm.startPrank(ALICE); - commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint240(0)))); + commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(0), uint16(0)))); // Attempt to end the battle immediately (same block as start) // Bob hasn't committed and timeout is 0, so Bob loses, but game should revert @@ -2722,10 +2722,10 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey, uint8 aliceMoveIndex, uint8 bobMoveIndex, - uint240 aliceExtraData, - uint240 bobExtraData + uint16 aliceExtraData, + uint16 bobExtraData ) internal { - bytes32 salt = ""; + uint104 salt = 0; bytes32 aliceMoveHash = keccak256(abi.encodePacked(aliceMoveIndex, salt, aliceExtraData)); bytes32 bobMoveHash = keccak256(abi.encodePacked(bobMoveIndex, salt, bobExtraData)); // Decide which player commits @@ -2830,8 +2830,8 @@ contract EngineTest is Test, BattleHelper { */ function test_turn0DefaultCommitManagerValidPreimage() public { bytes32 battleKey = _startDummyBattleWithTwoMons(); - bytes32 salt = ""; - uint240 extraData = uint240(0); + uint104 salt = 0; + uint16 extraData = uint16(0); bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, extraData)); // Ensure Alice cannot reveal yet because Alice has not yet committed @@ -2889,8 +2889,8 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startDummyBattleWithTwoMons(); // Let Alice commit to choosing switch - bytes32 salt = ""; - uint240 extraData = uint240(0); + uint104 salt = 0; + uint16 extraData = uint16(0); bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, extraData)); // Let Alice commit the first move (switching in mon index 0) @@ -2910,7 +2910,7 @@ contract EngineTest is Test, BattleHelper { commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, extraData, true); engine.resetCallContext(); // New turn, both players swap to mon index 1 - extraData = uint240(1); + extraData = uint16(1); moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, extraData)); // Ensure Bob cannot reveal yet because Bob has not yet committed @@ -2936,7 +2936,7 @@ contract EngineTest is Test, BattleHelper { // Let Alice reveal their invalid move index of 0 vm.startPrank(ALICE); vm.expectRevert(abi.encodeWithSignature("InvalidMove(address)", ALICE)); - uint240 invalidExtraData = uint240(0); + uint16 invalidExtraData = uint16(0); commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, invalidExtraData, true); engine.resetCallContext(); // Now let Alice reveal a valid move @@ -2971,8 +2971,8 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startDummyBattleWithTwoMons(); // Let Alice commit to choosing switch - bytes32 salt = ""; - uint240 extraData = uint240(0); + uint104 salt = 0; + uint16 extraData = uint16(0); bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, extraData)); vm.startPrank(ALICE); commitManager.commitMove(battleKey, moveHash); @@ -2991,8 +2991,8 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startDummyBattleWithTwoMons(); // Let Alice commit to choosing switch - bytes32 salt = ""; - uint240 extraData = uint240(0); + uint104 salt = 0; + uint16 extraData = uint16(0); bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, extraData)); vm.startPrank(ALICE); commitManager.commitMove(battleKey, moveHash); @@ -3067,7 +3067,7 @@ contract EngineTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Let Alice and Bob commit and reveal to both choosing attack (move index 0) @@ -3111,9 +3111,9 @@ contract EngineTest is Test, BattleHelper { ); bytes32 battleKey = _startBattle(validatorToUse, engine, defaultOracle, defaultRegistry, matchmaker, address(commitManager)); // Alice sends in mon index 0, Bob sends in the fast mon - _commitRevealExecuteForAliceAndBob(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(1)); + _commitRevealExecuteForAliceAndBob(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(1)); // Both players pick move index 0 - _commitRevealExecuteForAliceAndBob(battleKey, 0, 0, uint240(1), uint240(0)); + _commitRevealExecuteForAliceAndBob(battleKey, 0, 0, uint16(1), uint16(0)); // Switch for turn flag should be 0, Bob's active mon index should now be 0 (, BattleData memory state) = engine.getBattle(battleKey); assertEq(state.playerSwitchForTurnFlag, 0); @@ -3139,15 +3139,15 @@ contract EngineTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validatorToUse, engine, defaultOracle, defaultRegistry, matchmaker, address(commitManager)); // Alice and Bob send in their first mon - _commitRevealExecuteForAliceAndBob(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); // Verify the dummy effect is applied to Alice's mon (EffectInstance[] memory effects, uint256[] memory indices) = engine.getEffects(battleKey, 1, 0); assertEq(effects.length, 1); // Alice uses the edit effect attack to change the extra data to 69 on Bob - // Pack extraData: lower 80 bits = targetIndex (1), next 80 bits = monIndex (0), upper 80 bits = effectIndex - uint240 editExtraData = uint240(1 | (0 << 80) | (indices[0] << 160)); + // Pack extraData: bits 0..1 = targetIndex (1), bits 2..5 = monIndex (0), bits 6..15 = effectIndex + uint16 editExtraData = uint16(uint256(1) | (uint256(0) << 2) | (uint256(indices[0]) << 6)); _commitRevealExecuteForAliceAndBob(battleKey, 0, NO_OP_MOVE_INDEX, editExtraData, 0); (effects, ) = engine.getEffects(battleKey, 1, 0); assertEq(effects[0].data, bytes32(uint256(69))); diff --git a/test/GachaTest.sol b/test/GachaTest.sol index ba3af067..f116e144 100644 --- a/test/GachaTest.sol +++ b/test/GachaTest.sol @@ -125,7 +125,7 @@ contract GachaTest is Test, BattleHelper { // Alice commits switching to mon index 0 vm.startPrank(ALICE); - commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint240(0)))); + commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint16(0)))); // Alice wins the battle (inactivity for Bob), we skip ahead mockRNG.setRNG(1); // No extra bonus for points @@ -197,7 +197,7 @@ contract GachaTest is Test, BattleHelper { // Alice commits switching to mon index 0 vm.startPrank(ALICE); - commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint240(0)))); + commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint16(0)))); // Alice wins the battle engine.end(battleKey); @@ -295,7 +295,7 @@ contract GachaTest is Test, BattleHelper { _startBattle(validator, engine, defaultOracle, defaultRegistry, matchmaker, hooks, address(commitManager)); vm.warp(vm.getBlockTimestamp() + 1); vm.startPrank(ALICE); - commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint240(0)))); + commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint16(0)))); vm.stopPrank(); mockRNG.setRNG(1); engine.end(battleKey); @@ -318,7 +318,7 @@ contract GachaTest is Test, BattleHelper { _startBattle(validator, engine, defaultOracle, defaultRegistry, matchmaker, hooks, address(commitManager)); vm.warp(vm.getBlockTimestamp() + 1); vm.startPrank(ALICE); - commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint240(0)))); + commitManager.commitMove(battleKey, keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(""), uint16(0)))); vm.stopPrank(); mockRNG.setRNG(1); engine.end(battleKey); diff --git a/test/InlineAbilityParityTest.sol b/test/InlineAbilityParityTest.sol index 7320fff7..0bbf6940 100644 --- a/test/InlineAbilityParityTest.sol +++ b/test/InlineAbilityParityTest.sol @@ -117,7 +117,7 @@ contract InlineAbilityParityTest is Test, BattleHelper { // Turn 0: both switch in _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); assertTrue(_hasEffect(battleKey, 0, 0, address(singletonAbility)), "p0 should have effect"); @@ -139,18 +139,18 @@ contract InlineAbilityParityTest is Test, BattleHelper { // Turn 0: switch in mon 0 _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); assertEq(_countEffect(battleKey, 0, 0, address(singletonAbility)), 1, "should have 1 effect"); // Switch to mon 1 then back to mon 0 _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); assertEq(_countEffect(battleKey, 0, 0, address(singletonAbility)), 1, "should still have exactly 1 effect"); @@ -170,7 +170,7 @@ contract InlineAbilityParityTest is Test, BattleHelper { // Turn 0 _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Execute 2 attack turns — AfterDamage should increment counter each time @@ -205,7 +205,7 @@ contract InlineAbilityParityTest is Test, BattleHelper { // Turn 0 _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // EffectAbility adds dummyEffect — verify it's registered @@ -233,14 +233,14 @@ contract InlineAbilityParityTest is Test, BattleHelper { // Turn 0: switch in mon 0 (inline) _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); assertTrue(_hasEffect(battleKey, 0, 0, address(singletonAbility)), "alice mon 0 should have inline effect"); // Alice switches to mon 1 (external) _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); assertTrue(_hasEffect(battleKey, 0, 1, address(dummyEffect)), "alice mon 1 should have external effect"); } @@ -260,7 +260,7 @@ contract InlineAbilityParityTest is Test, BattleHelper { _commitRevealExecuteForAliceAndBob( engine, commitManager, battleKey, - SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); assertTrue(_hasEffect(battleKey, 0, 0, address(singletonAbility)), "p0 should have inline effect"); diff --git a/test/InlineEngineGasTest.sol b/test/InlineEngineGasTest.sol index 579b6e95..19842928 100644 --- a/test/InlineEngineGasTest.sol +++ b/test/InlineEngineGasTest.sol @@ -15,7 +15,7 @@ import {SignedCommitManager} from "../src/commit-manager/SignedCommitManager.sol import {Engine} from "../src/Engine.sol"; import {IEngine} from "../src/IEngine.sol"; import {IValidator} from "../src/IValidator.sol"; -import {EIP712} from "../src/lib/EIP712.sol"; +import {SignedCommitHelper} from "./abstract/SignedCommitHelper.sol"; import {IEffect} from "../src/effects/IEffect.sol"; import {StaminaRegen} from "../src/effects/StaminaRegen.sol"; @@ -60,10 +60,6 @@ contract InlineEngineGasTest is Test, BattleHelper { uint256 constant MONS_PER_TEAM = 4; uint256 constant MOVES_PER_MON = 4; - function _packStatBoost(uint256 playerIndex, uint256 monIndex, uint256 statIndex, int32 boostAmount) internal pure returns (uint240) { - return uint240(playerIndex | (monIndex << 60) | (statIndex << 120) | (uint256(uint32(boostAmount)) << 180)); - } - function setUp() public { defaultOracle = new DefaultRandomnessOracle(); // Create engine with inline validation defaults @@ -162,26 +158,26 @@ contract InlineEngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("FirstBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 1, 0, 0); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(0), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(0), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 3, NO_OP_MOVE_INDEX, 0, 0); vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); uint256 firstBattleGas = vm.stopSnapshotGas("FirstBattle"); @@ -209,27 +205,27 @@ contract InlineEngineGasTest is Test, BattleHelper { console.log("After setup 2 - packedP1EffectsCount:", cfgAfterSetup2.packedP1EffectsCount); vm.startSnapshotGas("SecondBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, 1, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, 2, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, SWITCH_MOVE_INDEX, 2, uint16(1), 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, NO_OP_MOVE_INDEX, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, NO_OP_MOVE_INDEX, 3, 0, _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, NO_OP_MOVE_INDEX, 0, 0, 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 3, 3, _packStatBoost(0, 2, uint256(MonStateIndexName.Attack), int32(90)), _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); vm.startPrank(BOB); - commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey2, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); uint256 secondBattleGas = vm.stopSnapshotGas("SecondBattle"); @@ -252,26 +248,26 @@ contract InlineEngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("ThirdBattle"); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 0, 1, 0, 0); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(0), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(0), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, 3, NO_OP_MOVE_INDEX, 0, 0); vm.startPrank(BOB); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); vm.startPrank(ALICE); - commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint240(3), true); + commitManager.revealMove(battleKey3, SWITCH_MOVE_INDEX, 0, uint16(3), true); engine.resetCallContext(); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); uint256 thirdBattleGas = vm.stopSnapshotGas("ThirdBattle"); @@ -338,7 +334,7 @@ contract InlineEngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Battle1_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey1, 0, 0, 0, 0); uint256 execute1 = vm.stopSnapshotGas("Battle1_Execute"); @@ -350,7 +346,7 @@ contract InlineEngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Battle2_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, 0, 0, 0, 0); uint256 execute2 = vm.stopSnapshotGas("Battle2_Execute"); @@ -412,7 +408,7 @@ contract InlineEngineGasTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("B1_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey1, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); (BattleConfigView memory cfgAfterSwitch,) = inlineEngine.getBattle(battleKey1); console.log("After B1 switch - globalEffectsLength:", cfgAfterSwitch.globalEffectsLength); @@ -445,7 +441,7 @@ contract InlineEngineGasTest is Test, BattleHelper { console.log("After B2 setup - packedP1EffectsCount:", cfg2.packedP1EffectsCount); vm.startSnapshotGas("B2_Execute"); - _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, 0, 0, 0, 0); _commitRevealExecuteForEngine(inlineEngine, inlineCommitManager, battleKey2, 1, 1, 0, 0); uint256 execute2 = vm.stopSnapshotGas("B2_Execute"); @@ -525,10 +521,10 @@ contract InlineEngineGasTest is Test, BattleHelper { bytes32 battleKey, uint8 aliceMoveIndex, uint8 bobMoveIndex, - uint240 aliceExtraData, - uint240 bobExtraData + uint16 aliceExtraData, + uint16 bobExtraData ) internal { - bytes32 salt = ""; + uint104 salt = 0; bytes32 aliceMoveHash = keccak256(abi.encodePacked(aliceMoveIndex, salt, aliceExtraData)); bytes32 bobMoveHash = keccak256(abi.encodePacked(bobMoveIndex, salt, bobExtraData)); uint256 turnId = eng.getTurnIdForBattleState(battleKey); @@ -563,7 +559,7 @@ contract InlineEngineGasTest is Test, BattleHelper { /// SignedMatchmaker (no propose/accept/confirm storage), and /// SignedCommitManager::executeWithDualSignedMoves (1 TX per two-player turn). /// @dev Forced single-player switches after KOs use SignedCommitManager::executeSinglePlayerMove. -contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { +contract FullyOptimizedInlineGasTest is BattleHelper, SignedCommitHelper { uint256 constant MONS_PER_TEAM = 4; uint256 constant MOVES_PER_MON = 4; @@ -584,14 +580,6 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { mapping(bytes32 => bool) private _seenSlot; bytes32[] private _seenKeys; - function _domainNameAndVersion() internal pure override returns (string memory, string memory) { - return ("SignedCommitManager", "1"); - } - - function _packStatBoost(uint256 playerIndex, uint256 monIndex, uint256 statIndex, int32 boostAmount) internal pure returns (uint240) { - return uint240(playerIndex | (monIndex << 60) | (statIndex << 120) | (uint256(uint32(boostAmount)) << 180)); - } - function setUp() public { p0 = vm.addr(P0_PK); p1 = vm.addr(P1_PK); @@ -645,39 +633,6 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { return battleKey; } - function _signDualReveal( - uint256 privateKey, - bytes32 battleKey, - uint64 turnId, - bytes32 committerMoveHash, - uint8 revealerMoveIndex, - bytes32 revealerSalt, - uint240 revealerExtraData - ) internal view returns (bytes memory) { - bytes32 domainSeparator = keccak256( - abi.encode( - _DOMAIN_TYPEHASH, - keccak256("SignedCommitManager"), - keccak256("1"), - block.chainid, - address(signedCommitManager) - ) - ); - bytes32 structHash = SignedCommitLib.hashDualSignedReveal( - SignedCommitLib.DualSignedReveal({ - battleKey: battleKey, - turnId: turnId, - committerMoveHash: committerMoveHash, - revealerMoveIndex: revealerMoveIndex, - revealerSalt: revealerSalt, - revealerExtraData: revealerExtraData - }) - ); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - return abi.encodePacked(r, s, v); - } - /// @dev Executes a two-player turn in 1 TX via executeWithDualSignedMoves. /// p0Move/p1Move semantics match _commitRevealExecuteForAliceAndBob so the /// battle scripts can be transcribed directly from the non-optimized test. @@ -685,17 +640,18 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { bytes32 battleKey, uint8 p0MoveIndex, uint8 p1MoveIndex, - uint240 p0ExtraData, - uint240 p1ExtraData + uint16 p0ExtraData, + uint16 p1ExtraData ) internal { uint64 turnId = uint64(engine.getTurnIdForBattleState(battleKey)); - bytes32 committerSalt = keccak256(abi.encode("committer", battleKey, turnId)); - bytes32 revealerSalt = keccak256(abi.encode("revealer", battleKey, turnId)); + uint104 committerSalt = uint104(uint256(keccak256(abi.encode("committer", battleKey, turnId)))); + uint104 revealerSalt = uint104(uint256(keccak256(abi.encode("revealer", battleKey, turnId)))); uint8 committerMoveIndex; - uint240 committerExtraData; + uint16 committerExtraData; uint8 revealerMoveIndex; - uint240 revealerExtraData; + uint16 revealerExtraData; + uint256 committerPk; uint256 revealerPk; address committer; @@ -704,6 +660,7 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { committerExtraData = p0ExtraData; revealerMoveIndex = p1MoveIndex; revealerExtraData = p1ExtraData; + committerPk = P0_PK; revealerPk = P1_PK; committer = p0; } else { @@ -711,14 +668,17 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { committerExtraData = p1ExtraData; revealerMoveIndex = p0MoveIndex; revealerExtraData = p0ExtraData; + committerPk = P1_PK; revealerPk = P0_PK; committer = p1; } bytes32 committerMoveHash = keccak256(abi.encodePacked(committerMoveIndex, committerSalt, committerExtraData)); + address mgr = address(signedCommitManager); + bytes memory committerSig = _signCommit(mgr, committerPk, committerMoveHash, battleKey, turnId); bytes memory revealerSig = _signDualReveal( - revealerPk, battleKey, turnId, committerMoveHash, + mgr, revealerPk, battleKey, turnId, committerMoveHash, revealerMoveIndex, revealerSalt, revealerExtraData ); @@ -727,16 +687,16 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { battleKey, committerMoveIndex, committerSalt, committerExtraData, revealerMoveIndex, revealerSalt, revealerExtraData, - revealerSig + committerSig, revealerSig ); engine.resetCallContext(); } /// @dev Single-player forced switch after a KO. This uses the optimized /// SignedCommitManager path because there is no hidden opponent move to reveal. - function _fastSwitchReveal(bytes32 battleKey, bool isP0, uint240 extraData) internal { + function _fastSwitchReveal(bytes32 battleKey, bool isP0, uint16 extraData) internal { vm.prank(isP0 ? p0 : p1); - signedCommitManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), extraData); + signedCommitManager.executeSinglePlayerMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), extraData); engine.resetCallContext(); } @@ -768,43 +728,43 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { bytes32 oldFlowBattleKey = _startBattleFullyOptimized(ruleset); vm.warp(vm.getBlockTimestamp() + 1); - _fastTurn(oldFlowBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); - _fastTurn(oldFlowBattleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(oldFlowBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); + _fastTurn(oldFlowBattleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0)); assertEq(engine.getPlayerSwitchForTurnFlagForBattleState(oldFlowBattleKey), 1); vm.prank(p1); uint256 gasBefore = gasleft(); - signedCommitManager.revealMove(oldFlowBattleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(1), true); + signedCommitManager.revealMove(oldFlowBattleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), true); uint256 oldFlowGas = gasBefore - gasleft(); engine.resetCallContext(); - _fastTurn(oldFlowBattleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(oldFlowBattleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0)); assertEq(engine.getPlayerSwitchForTurnFlagForBattleState(oldFlowBattleKey), 1); vm.prank(p1); gasBefore = gasleft(); - signedCommitManager.revealMove(oldFlowBattleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(2), true); + signedCommitManager.revealMove(oldFlowBattleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(2), true); uint256 oldFlowSecondGas = gasBefore - gasleft(); engine.resetCallContext(); bytes32 fastPathBattleKey = _startBattleFullyOptimized(ruleset); vm.warp(vm.getBlockTimestamp() + 1); - _fastTurn(fastPathBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); - _fastTurn(fastPathBattleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(fastPathBattleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); + _fastTurn(fastPathBattleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0)); assertEq(engine.getPlayerSwitchForTurnFlagForBattleState(fastPathBattleKey), 1); vm.prank(p1); gasBefore = gasleft(); - signedCommitManager.executeSinglePlayerMove(fastPathBattleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(1)); + signedCommitManager.executeSinglePlayerMove(fastPathBattleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1)); uint256 fastPathGas = gasBefore - gasleft(); engine.resetCallContext(); - _fastTurn(fastPathBattleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(fastPathBattleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0)); assertEq(engine.getPlayerSwitchForTurnFlagForBattleState(fastPathBattleKey), 1); vm.prank(p1); gasBefore = gasleft(); - signedCommitManager.executeSinglePlayerMove(fastPathBattleKey, SWITCH_MOVE_INDEX, bytes32(0), uint240(2)); + signedCommitManager.executeSinglePlayerMove(fastPathBattleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(2)); uint256 fastPathSecondGas = gasBefore - gasleft(); engine.resetCallContext(); @@ -857,19 +817,19 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Fast_Battle1"); - _fastTurn(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _fastTurn(battleKey, 0, 1, 0, 0); - _fastTurn(battleKey, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _fastTurn(battleKey, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); - _fastSwitchReveal(battleKey, true, uint240(0)); + _fastSwitchReveal(battleKey, true, uint16(0)); _fastTurn(battleKey, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _fastTurn(battleKey, 3, NO_OP_MOVE_INDEX, 0, 0); - _fastSwitchReveal(battleKey, false, uint240(1)); + _fastSwitchReveal(battleKey, false, uint16(1)); _fastTurn(battleKey, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); - _fastSwitchReveal(battleKey, true, uint240(2)); + _fastSwitchReveal(battleKey, true, uint16(2)); _fastTurn(battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); - _fastSwitchReveal(battleKey, true, uint240(3)); + _fastSwitchReveal(battleKey, true, uint16(3)); _fastTurn(battleKey, NO_OP_MOVE_INDEX, 3, 0, 0); uint256 firstBattleGas = vm.stopSnapshotGas("Fast_Battle1"); @@ -891,20 +851,20 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Fast_Battle2"); - _fastTurn(battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _fastTurn(battleKey2, 3, 1, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _fastTurn(battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); - _fastSwitchReveal(battleKey2, false, uint240(1)); - _fastTurn(battleKey2, SWITCH_MOVE_INDEX, 2, uint240(1), 0); + _fastSwitchReveal(battleKey2, false, uint16(1)); + _fastTurn(battleKey2, SWITCH_MOVE_INDEX, 2, uint16(1), 0); _fastTurn(battleKey2, 3, NO_OP_MOVE_INDEX, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); _fastTurn(battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); - _fastSwitchReveal(battleKey2, false, uint240(2)); + _fastSwitchReveal(battleKey2, false, uint16(2)); _fastTurn(battleKey2, NO_OP_MOVE_INDEX, 3, 0, _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey2, NO_OP_MOVE_INDEX, 0, 0, 0); - _fastSwitchReveal(battleKey2, true, uint240(2)); + _fastSwitchReveal(battleKey2, true, uint16(2)); _fastTurn(battleKey2, 3, 3, _packStatBoost(0, 2, uint256(MonStateIndexName.Attack), int32(90)), _packStatBoost(1, 2, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); - _fastSwitchReveal(battleKey2, false, uint240(3)); + _fastSwitchReveal(battleKey2, false, uint16(3)); _fastTurn(battleKey2, 0, NO_OP_MOVE_INDEX, 0, 0); uint256 secondBattleGas = vm.stopSnapshotGas("Fast_Battle2"); @@ -926,19 +886,19 @@ contract FullyOptimizedInlineGasTest is Test, BattleHelper, EIP712 { vm.warp(vm.getBlockTimestamp() + 1); vm.startSnapshotGas("Fast_Battle3"); - _fastTurn(battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(battleKey3, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _fastTurn(battleKey3, 0, 1, 0, 0); - _fastTurn(battleKey3, SWITCH_MOVE_INDEX, 2, uint240(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); + _fastTurn(battleKey3, SWITCH_MOVE_INDEX, 2, uint16(1), _packStatBoost(1, 0, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey3, 2, 3, _packStatBoost(0, 1, uint256(MonStateIndexName.Attack), int32(90)), 0); - _fastSwitchReveal(battleKey3, true, uint240(0)); + _fastSwitchReveal(battleKey3, true, uint16(0)); _fastTurn(battleKey3, 2, NO_OP_MOVE_INDEX, _packStatBoost(0, 0, uint256(MonStateIndexName.Attack), int32(90)), 0); _fastTurn(battleKey3, 3, NO_OP_MOVE_INDEX, 0, 0); - _fastSwitchReveal(battleKey3, false, uint240(1)); + _fastSwitchReveal(battleKey3, false, uint16(1)); _fastTurn(battleKey3, NO_OP_MOVE_INDEX, 2, 0, _packStatBoost(1, 1, uint256(MonStateIndexName.Attack), int32(90))); _fastTurn(battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); - _fastSwitchReveal(battleKey3, true, uint240(2)); + _fastSwitchReveal(battleKey3, true, uint16(2)); _fastTurn(battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); - _fastSwitchReveal(battleKey3, true, uint240(3)); + _fastSwitchReveal(battleKey3, true, uint16(3)); _fastTurn(battleKey3, NO_OP_MOVE_INDEX, 3, 0, 0); uint256 thirdBattleGas = vm.stopSnapshotGas("Fast_Battle3"); diff --git a/test/InlineMoveParityTest.sol b/test/InlineMoveParityTest.sol index 019395f0..7ffaeaf4 100644 --- a/test/InlineMoveParityTest.sol +++ b/test/InlineMoveParityTest.sol @@ -111,9 +111,9 @@ contract InlineMoveParityTest is Test, BattleHelper { } function _doSwitchTurn(bytes32 battleKey) internal { - bytes32 salt = ""; + uint104 salt = 0; uint256 turnId = engine.getTurnIdForBattleState(battleKey); - bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + bytes32 moveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); if (turnId % 2 == 0) { vm.startPrank(ALICE); commitManager.commitMove(battleKey, moveHash); @@ -134,10 +134,10 @@ contract InlineMoveParityTest is Test, BattleHelper { } function _doAttackTurn(bytes32 battleKey, uint8 aliceMove, uint8 bobMove) internal { - bytes32 salt = ""; + uint104 salt = 0; uint256 turnId = engine.getTurnIdForBattleState(battleKey); if (turnId % 2 == 0) { - bytes32 moveHash = keccak256(abi.encodePacked(aliceMove, salt, uint240(0))); + bytes32 moveHash = keccak256(abi.encodePacked(aliceMove, salt, uint16(0))); vm.startPrank(ALICE); commitManager.commitMove(battleKey, moveHash); vm.startPrank(BOB); @@ -145,7 +145,7 @@ contract InlineMoveParityTest is Test, BattleHelper { vm.startPrank(ALICE); commitManager.revealMove(battleKey, aliceMove, salt, 0, true); } else { - bytes32 moveHash = keccak256(abi.encodePacked(bobMove, salt, uint240(0))); + bytes32 moveHash = keccak256(abi.encodePacked(bobMove, salt, uint16(0))); vm.startPrank(BOB); commitManager.commitMove(battleKey, moveHash); vm.startPrank(ALICE); diff --git a/test/InlineValidationTest.sol b/test/InlineValidationTest.sol index 823bd40c..229f9083 100644 --- a/test/InlineValidationTest.sol +++ b/test/InlineValidationTest.sol @@ -125,9 +125,9 @@ contract InlineValidationTest is Test, BattleHelper { bytes32 battleKey = _startBattleWithInlineValidation(); // Both players switch in mon 0 - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); - bytes32 p1MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); + bytes32 p1MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); @@ -150,8 +150,8 @@ contract InlineValidationTest is Test, BattleHelper { bytes32 battleKey = _startBattleWithInlineValidation(); // Both players switch in mon 0 - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); @@ -161,7 +161,7 @@ contract InlineValidationTest is Test, BattleHelper { commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, salt, 0, true); engine.resetCallContext(); // Now use move 0 (attack) - bytes32 p0AttackHash = keccak256(abi.encodePacked(uint8(0), salt, uint240(0))); + bytes32 p0AttackHash = keccak256(abi.encodePacked(uint8(0), salt, uint16(0))); vm.startPrank(p1); commitManager.commitMove(battleKey, p0AttackHash); @@ -180,8 +180,8 @@ contract InlineValidationTest is Test, BattleHelper { bytes32 battleKey = _startBattleWithInlineValidation(); // Both players switch in mon 0 - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); @@ -192,7 +192,7 @@ contract InlineValidationTest is Test, BattleHelper { engine.resetCallContext(); // P1 commits turn 1 - try to switch to mon 0 again (invalid - already active) // The inline validation should treat this as invalid and fall through - bytes32 p1InvalidSwitchHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + bytes32 p1InvalidSwitchHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p1); commitManager.commitMove(battleKey, p1InvalidSwitchHash); @@ -213,10 +213,10 @@ contract InlineValidationTest is Test, BattleHelper { /// @notice Test multiple turns with inline validation function test_inlineValidation_multipleRounds() public { bytes32 battleKey = _startBattleWithInlineValidation(); - bytes32 salt = ""; + uint104 salt = 0; // Turn 0: Both switch in mon 0 - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); vm.startPrank(p1); @@ -233,7 +233,7 @@ contract InlineValidationTest is Test, BattleHelper { if (bd.playerSwitchForTurnFlag != 2) break; uint256 turnId = engine.getTurnIdForBattleState(battleKey); - bytes32 attackHash = keccak256(abi.encodePacked(uint8(0), salt, uint240(0))); + bytes32 attackHash = keccak256(abi.encodePacked(uint8(0), salt, uint16(0))); if (turnId % 2 == 0) { vm.startPrank(p0); @@ -290,8 +290,8 @@ contract InlineValidationTest is Test, BattleHelper { bytes32 battleKey = _startBattleWithInlineValidation(); // Complete turn 0 switches - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); vm.startPrank(p1); @@ -321,8 +321,8 @@ contract InlineValidationTest is Test, BattleHelper { bytes32 battleKey = _startBattleWithInlineValidation(); // Complete turn 0 switches - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); vm.startPrank(p1); @@ -419,8 +419,8 @@ contract InlineValidationTest is Test, BattleHelper { (bytes32 battleKey, DefaultValidator externalValidator) = _startBattleWithExternalValidator(); // Complete turn 0 switches - bytes32 salt = ""; - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint240(0))); + uint104 salt = 0; + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, salt, uint16(0))); vm.startPrank(p0); commitManager.commitMove(battleKey, p0MoveHash); vm.startPrank(p1); @@ -488,7 +488,7 @@ contract InlineValidationTest is Test, BattleHelper { // P0 selects mon 0, CPU will randomly select (mockRNG returns 0, so mon 0) mockRNG.setRNG(0); - cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, "", 0); + cpu.selectMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), 0); // Verify both players switched in assertEq(engine.getActiveMonIndexForBattleState(battleKey)[0], 0, "P0 should have mon 0 active"); @@ -504,7 +504,7 @@ contract InlineValidationTest is Test, BattleHelper { // P0 uses attack, CPU will use attack (mockRNG selects index 1 which is the move) mockRNG.setRNG(1); - cpu.selectMove(battleKey, 0, "", 0); + cpu.selectMove(battleKey, 0, uint104(0), 0); // Battle should have advanced to turn 2 uint256 turnId = engine.getTurnIdForBattleState(battleKey); diff --git a/test/MatchmakerTest.sol b/test/MatchmakerTest.sol index 8678845f..54892be9 100644 --- a/test/MatchmakerTest.sol +++ b/test/MatchmakerTest.sol @@ -393,7 +393,7 @@ contract MatchmakerTest is Test, BattleHelper { assertEq(battleData.p1, BOB); // Check that Alice and Bob can commit/reveal/reveal to switch to mon index 0 - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); } function test_fastBattleSucceedsAndNoSubsequentAccept() public { diff --git a/test/SignedCommitManager.t.sol b/test/SignedCommitManager.t.sol index f9220256..43abefe3 100644 --- a/test/SignedCommitManager.t.sol +++ b/test/SignedCommitManager.t.sol @@ -17,11 +17,11 @@ import {MockRandomnessOracle} from "./mocks/MockRandomnessOracle.sol"; import {TestTeamRegistry} from "./mocks/TestTeamRegistry.sol"; import {DefaultMatchmaker} from "../src/matchmaker/DefaultMatchmaker.sol"; import {BattleHelper} from "./abstract/BattleHelper.sol"; +import {SignedCommitHelper} from "./abstract/SignedCommitHelper.sol"; import {SignedCommitLib} from "../src/commit-manager/SignedCommitLib.sol"; import {TestMoveFactory} from "./mocks/TestMoveFactory.sol"; -import {EIP712} from "../src/lib/EIP712.sol"; -abstract contract SignedCommitManagerTestBase is Test, BattleHelper, EIP712 { +abstract contract SignedCommitManagerTestBase is BattleHelper, SignedCommitHelper { Engine engine; SignedCommitManager signedCommitManager; MockRandomnessOracle mockOracle; @@ -36,11 +36,6 @@ abstract contract SignedCommitManagerTestBase is Test, BattleHelper, EIP712 { address p0; address p1; - // Required by EIP712 inheritance (only used to access _DOMAIN_TYPEHASH) - function _domainNameAndVersion() internal pure override returns (string memory, string memory) { - return ("SignedCommitManager", "1"); - } - function setUp() public virtual { p0 = vm.addr(P0_PK); p1 = vm.addr(P1_PK); @@ -130,96 +125,19 @@ abstract contract SignedCommitManagerTestBase is Test, BattleHelper, EIP712 { return battleKey; } - /// @dev Signs a DualSignedReveal struct for the revealer - /// @param privateKey The revealer's private key - /// @param battleKey The battle identifier - /// @param turnId The current turn ID - /// @param committerMoveHash The committer's move hash (that revealer signs over) - /// @param revealerMoveIndex The revealer's move index - /// @param revealerSalt The revealer's salt - /// @param revealerExtraData The revealer's extra data - function _signDualReveal( - uint256 privateKey, - bytes32 battleKey, - uint64 turnId, - bytes32 committerMoveHash, - uint8 revealerMoveIndex, - bytes32 revealerSalt, - uint240 revealerExtraData - ) internal view returns (bytes memory) { - bytes32 domainSeparator = keccak256( - abi.encode( - _DOMAIN_TYPEHASH, - keccak256("SignedCommitManager"), - keccak256("1"), - block.chainid, - address(signedCommitManager) - ) - ); - - bytes32 structHash = SignedCommitLib.hashDualSignedReveal( - SignedCommitLib.DualSignedReveal({ - battleKey: battleKey, - turnId: turnId, - committerMoveHash: committerMoveHash, - revealerMoveIndex: revealerMoveIndex, - revealerSalt: revealerSalt, - revealerExtraData: revealerExtraData - }) - ); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - return abi.encodePacked(r, s, v); - } - - /// @dev Signs a SignedCommit struct for the committer - /// @param privateKey The committer's private key - /// @param moveHash The committer's move hash - /// @param battleKey The battle identifier - /// @param turnId The current turn ID - function _signCommit( - uint256 privateKey, - bytes32 moveHash, - bytes32 battleKey, - uint64 turnId - ) internal view returns (bytes memory) { - bytes32 domainSeparator = keccak256( - abi.encode( - _DOMAIN_TYPEHASH, - keccak256("SignedCommitManager"), - keccak256("1"), - block.chainid, - address(signedCommitManager) - ) - ); - - bytes32 structHash = SignedCommitLib.hashSignedCommit( - SignedCommitLib.SignedCommit({ - moveHash: moveHash, - battleKey: battleKey, - turnId: turnId - }) - ); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - return abi.encodePacked(r, s, v); - } - /// @dev Completes a turn using the normal commit-reveal flow. /// Turn 0 uses SWITCH_MOVE_INDEX; subsequent turns use NO_OP_MOVE_INDEX. function _completeTurnNormal(bytes32 battleKey, uint256 turnId) internal { - bytes32 salt = bytes32(turnId + 1); + uint104 salt = uint104(turnId + 1); uint8 moveIndex = turnId == 0 ? SWITCH_MOVE_INDEX : NO_OP_MOVE_INDEX; - bytes32 moveHash = keccak256(abi.encodePacked(moveIndex, salt, uint240(0))); + bytes32 moveHash = keccak256(abi.encodePacked(moveIndex, salt, uint16(0))); if (turnId % 2 == 0) { // p0 commits vm.startPrank(p0); signedCommitManager.commitMove(battleKey, moveHash); vm.startPrank(p1); - signedCommitManager.revealMove(battleKey, moveIndex, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, moveIndex, uint104(0), 0, false); vm.startPrank(p0); signedCommitManager.revealMove(battleKey, moveIndex, salt, 0, true); } else { @@ -227,7 +145,7 @@ abstract contract SignedCommitManagerTestBase is Test, BattleHelper, EIP712 { vm.startPrank(p1); signedCommitManager.commitMove(battleKey, moveHash); vm.startPrank(p0); - signedCommitManager.revealMove(battleKey, moveIndex, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, moveIndex, uint104(0), 0, false); vm.startPrank(p1); signedCommitManager.revealMove(battleKey, moveIndex, salt, 0, true); } @@ -238,44 +156,31 @@ abstract contract SignedCommitManagerTestBase is Test, BattleHelper, EIP712 { /// @dev Completes a turn using the dual-signed flow (1 TX). /// Turn 0 uses SWITCH_MOVE_INDEX; subsequent turns use NO_OP_MOVE_INDEX. function _completeTurnFast(bytes32 battleKey, uint256 turnId) internal { - bytes32 committerSalt = bytes32(turnId + 1); - bytes32 revealerSalt = bytes32(turnId + 2); + uint104 committerSalt = uint104(turnId + 1); + uint104 revealerSalt = uint104(turnId + 2); uint8 moveIndex = turnId == 0 ? SWITCH_MOVE_INDEX : NO_OP_MOVE_INDEX; - bytes32 committerMoveHash = keccak256(abi.encodePacked(moveIndex, committerSalt, uint240(0))); + bytes32 committerMoveHash = keccak256(abi.encodePacked(moveIndex, committerSalt, uint16(0))); - if (turnId % 2 == 0) { - // p0 is committer, p1 is revealer - bytes memory revealerSignature = _signDualReveal( - P1_PK, battleKey, uint64(turnId), committerMoveHash, moveIndex, revealerSalt, 0 - ); - vm.startPrank(p0); - signedCommitManager.executeWithDualSignedMoves( - battleKey, - moveIndex, - committerSalt, - 0, - moveIndex, - revealerSalt, - 0, - revealerSignature - ); - } else { - // p1 is committer, p0 is revealer - bytes memory revealerSignature = _signDualReveal( - P0_PK, battleKey, uint64(turnId), committerMoveHash, moveIndex, revealerSalt, 0 - ); - vm.startPrank(p1); - signedCommitManager.executeWithDualSignedMoves( - battleKey, - moveIndex, - committerSalt, - 0, - moveIndex, - revealerSalt, - 0, - revealerSignature - ); - } + (uint256 committerPk, uint256 revealerPk) = turnId % 2 == 0 ? (P0_PK, P1_PK) : (P1_PK, P0_PK); + bytes memory committerSignature = + _signCommit(address(signedCommitManager), committerPk, committerMoveHash, battleKey, uint64(turnId)); + bytes memory revealerSignature = _signDualReveal(address(signedCommitManager), + revealerPk, battleKey, uint64(turnId), committerMoveHash, moveIndex, revealerSalt, 0 + ); + + // Caller can be anyone; pick committer for parity with old test setup. + vm.startPrank(turnId % 2 == 0 ? p0 : p1); + signedCommitManager.executeWithDualSignedMoves( + battleKey, + moveIndex, + committerSalt, + 0, + moveIndex, + revealerSalt, + 0, + committerSignature, + revealerSignature + ); vm.stopPrank(); engine.resetCallContext(); } @@ -294,12 +199,13 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { uint64 turnId = 0; // p0 creates commitment hash off-chain - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - // p1 signs their move + p0's hash - bytes32 p1Salt = bytes32(uint256(2)); - bytes memory p1Signature = _signDualReveal( + // p0 signs their commitment, p1 signs their move + p0's hash + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, turnId); + uint104 p1Salt = uint104(2); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), P1_PK, battleKey, turnId, p0MoveHash, SWITCH_MOVE_INDEX, p1Salt, 0 ); @@ -313,6 +219,7 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { SWITCH_MOVE_INDEX, p1Salt, 0, + p0CommitSig, p1Signature ); @@ -333,11 +240,12 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { // Turn 1: p1 is committer, p0 is revealer uint64 turnId = 1; - bytes32 p1Salt = bytes32(uint256(2)); - bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint240(0))); + uint104 p1Salt = uint104(2); + bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint16(0))); + bytes memory p1CommitSig = _signCommit(address(signedCommitManager), P1_PK, p1MoveHash, battleKey, turnId); - bytes32 p0Salt = bytes32(uint256(3)); - bytes memory p0Signature = _signDualReveal( + uint104 p0Salt = uint104(3); + bytes memory p0Signature = _signDualReveal(address(signedCommitManager), P0_PK, battleKey, turnId, p1MoveHash, NO_OP_MOVE_INDEX, p0Salt, 0 ); @@ -350,6 +258,7 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { NO_OP_MOVE_INDEX, p0Salt, 0, + p1CommitSig, p0Signature ); @@ -418,7 +327,11 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_invalidSignature() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); + + // Valid committer sig, but garbage revealer sig. + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); bytes memory invalidSignature = abi.encodePacked(bytes32(uint256(1)), bytes32(uint256(2)), uint8(27)); vm.startPrank(p0); @@ -429,8 +342,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, invalidSignature ); } @@ -438,12 +352,13 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_wrongSigner() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - // p0 signs instead of p1 (wrong signer - should be revealer p1) - bytes memory wrongSignature = _signDualReveal( - P0_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); + // p0 signs the revealer slot instead of p1 (wrong signer - should be revealer p1) + bytes memory wrongSignature = _signDualReveal(address(signedCommitManager), + P0_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); vm.startPrank(p0); @@ -454,8 +369,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, wrongSignature ); } @@ -467,13 +383,14 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { _completeTurnNormal(battleKey, 0); _completeTurnNormal(battleKey, 1); - // On turn 2, p0 is committer again. Try to replay a turn 0 signature. - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint240(0))); + // On turn 2, p0 is committer again. Try to replay turn-0 signatures. + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint16(0))); - // Create signature for turn 0 (not current turn 2) - bytes memory turn0Signature = _signDualReveal( - P1_PK, battleKey, 0, p0MoveHash, NO_OP_MOVE_INDEX, bytes32(0), 0 + // Both signatures bound to turnId=0, replayed at turnId=2 + bytes memory turn0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); + bytes memory turn0Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0MoveHash, NO_OP_MOVE_INDEX, uint104(0), 0 ); vm.startPrank(p0); @@ -484,8 +401,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, NO_OP_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + turn0CommitSig, turn0Signature ); } @@ -493,15 +411,16 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_replayAttack_differentBattle() public { bytes32 battleKey1 = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - // Create signature for battle 1 - bytes memory battle1Signature = _signDualReveal( - P1_PK, battleKey1, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + // Both signatures bound to battle 1 + bytes memory battle1CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey1, 0); + bytes memory battle1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey1, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); - // Start second battle and try to use battle 1's signature + // Start second battle and try to use battle 1's signatures bytes32 battleKey2 = _startBattleWith(address(signedCommitManager)); vm.startPrank(p0); @@ -512,33 +431,146 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + battle1CommitSig, battle1Signature ); } - function test_revert_callerNotCommitter() public { + /// @notice Regression: a revealer alone (without an explicit committer signature) cannot + /// inject a self-chosen committer preimage `P*`. Previously this was blocked only by the + /// `msg.sender == committer` check; now both signatures are mandatory and bind each + /// player independently, so the check holds even under a relayer model. + function test_revert_executeWithDualSigned_unilateralRevealerAttack() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + // Attacker (p1, the revealer for turn 0) picks a preimage P* of their choosing for p0 + uint104 attackerCommitterSalt = uint104(0xdead); + uint16 attackerCommitterExtraData = 0; + uint8 attackerCommitterMoveIndex = SWITCH_MOVE_INDEX; + bytes32 chosenCommitterMoveHash = keccak256( + abi.encodePacked(attackerCommitterMoveIndex, attackerCommitterSalt, attackerCommitterExtraData) + ); - bytes memory p1Signature = _signDualReveal( - P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + // p1 signs the DualSignedReveal binding themselves to a chosen committer preimage + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, chosenCommitterMoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); - // p1 (revealer) tries to call executeWithDualSignedMoves - should fail - vm.startPrank(p1); - vm.expectRevert(SignedCommitManager.CallerNotCommitter.selector); + // Attacker forges a "committer signature" (signed by themselves, P1, over the same hash). + bytes memory forgedCommitterSig = _signCommit(address(signedCommitManager), P1_PK, chosenCommitterMoveHash, battleKey, 0); + + // _startBattleWith leaves an active prank on p0; clear it. + vm.stopPrank(); + + // Submit (from any sender) — committer sig recover will return p1, not p0 → revert. + vm.expectRevert(SignedCommitManager.InvalidSignature.selector); + signedCommitManager.executeWithDualSignedMoves( + battleKey, + attackerCommitterMoveIndex, + attackerCommitterSalt, + attackerCommitterExtraData, + SWITCH_MOVE_INDEX, + uint104(0), + 0, + forgedCommitterSig, + p1Signature + ); + } + + /// @notice Drops the old `msg.sender == committer` check: anyone can submit when both + /// EIP-712 signatures are present and valid (relayer-friendly). + function test_executeWithDualSigned_thirdPartyRelay_succeeds() public { + bytes32 battleKey = _startBattleWith(address(signedCommitManager)); + + uint104 p0Salt = uint104(1); + uint104 p1Salt = uint104(2); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); + + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, p1Salt, 0 + ); + + // _startBattleWith leaves an active prank on p0; clear it before pranking the relayer. + vm.stopPrank(); + + // A random third party (neither p0 nor p1) can submit the bundle. + address relayer = address(0xCAFE); + vm.prank(relayer); + signedCommitManager.executeWithDualSignedMoves( + battleKey, + SWITCH_MOVE_INDEX, + p0Salt, + 0, + SWITCH_MOVE_INDEX, + p1Salt, + 0, + p0CommitSig, + p1Signature + ); + + assertEq(engine.getTurnIdForBattleState(battleKey), 1, "Turn should advance via relayer"); + } + + /// @notice Wrong committer signer (sig recovers to revealer's address, not committer's) reverts. + function test_revert_executeWithDualSigned_wrongCommitterSigner() public { + bytes32 battleKey = _startBattleWith(address(signedCommitManager)); + + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); + + // p1 signs the SignedCommit instead of p0 → recovers to p1, not the committer p0. + bytes memory wrongCommitSig = _signCommit(address(signedCommitManager), P1_PK, p0MoveHash, battleKey, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 + ); + + vm.startPrank(p0); + vm.expectRevert(SignedCommitManager.InvalidSignature.selector); + signedCommitManager.executeWithDualSignedMoves( + battleKey, + SWITCH_MOVE_INDEX, + p0Salt, + 0, + SWITCH_MOVE_INDEX, + uint104(0), + 0, + wrongCommitSig, + p1Signature + ); + } + + /// @notice Committer signature over a different `moveHash` than the submitted preimage + /// reverts with InvalidSignature (the recovered hash differs from what the engine computes). + function test_revert_executeWithDualSigned_committerSigForWrongHash() public { + bytes32 battleKey = _startBattleWith(address(signedCommitManager)); + + uint104 p0Salt = uint104(1); + bytes32 p0DifferentMoveHash = + keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint16(0))); // committer signs over a different move + + bytes memory mismatchedCommitSig = _signCommit(address(signedCommitManager), P0_PK, p0DifferentMoveHash, battleKey, 0); + // Revealer signs the same different hash so the revealer side would have validated + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0DifferentMoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 + ); + + // p0 submits with their REAL move data (SWITCH_MOVE_INDEX, p0Salt, 0). Engine recomputes + // committerMoveHash from those fields → does not equal `p0DifferentMoveHash`. Committer sig + // recovery against the recomputed hash returns a non-p0 address → InvalidSignature. + vm.startPrank(p0); + vm.expectRevert(SignedCommitManager.InvalidSignature.selector); signedCommitManager.executeWithDualSignedMoves( battleKey, SWITCH_MOVE_INDEX, p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + mismatchedCommitSig, p1Signature ); } @@ -550,11 +582,12 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_battleNotStarted() public { bytes32 fakeBattleKey = bytes32(uint256(123)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - bytes memory p1Signature = _signDualReveal( - P1_PK, fakeBattleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, fakeBattleKey, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, fakeBattleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); vm.startPrank(p0); @@ -565,8 +598,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, p1Signature ); } @@ -577,14 +611,16 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { // Execute turn 0 with dual-signed flow _completeTurnFast(battleKey, 0); - // After turn 0, we're now on turn 1 where p1 is committer - // Try to replay with a turn 0 signature - fails because: - // 1. Turn has advanced, so signature turnId (0) doesn't match current turnId (1) - bytes32 p1Salt = bytes32(uint256(99)); - bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint240(0))); + // After turn 0, we're now on turn 1 where p1 is committer. + // Try to replay with turn-0 signatures - fails because turnId in sigs (0) doesn't + // match current turnId (1). + uint104 p1Salt = uint104(99); + bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint16(0))); - bytes memory p0Signature = _signDualReveal( - P0_PK, battleKey, 0, p1MoveHash, NO_OP_MOVE_INDEX, bytes32(0), 0 + // Both signatures are bound to turnId=0 (replay attempt) + bytes memory p1CommitSig = _signCommit(address(signedCommitManager), P1_PK, p1MoveHash, battleKey, 0); + bytes memory p0Signature = _signDualReveal(address(signedCommitManager), + P0_PK, battleKey, 0, p1MoveHash, NO_OP_MOVE_INDEX, uint104(0), 0 ); vm.startPrank(p1); @@ -595,8 +631,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p1Salt, 0, NO_OP_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p1CommitSig, p0Signature ); } @@ -604,11 +641,12 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_replayPrevented_sameBlockAttempt() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - bytes memory p1Signature = _signDualReveal( - P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); vm.startPrank(p0); @@ -618,22 +656,24 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, p1Signature ); - // After execution, turn advances to 1. On turn 1, p1 is committer, not p0. - // So if p0 tries to call again, it fails with CallerNotCommitter (turn parity changed) - vm.expectRevert(SignedCommitManager.CallerNotCommitter.selector); + // After execution, turn advances to 1. Replaying the same signatures (turnId=0) at + // turnId=1 fails on the committer signature recovery — sig was bound to turn 0. + vm.expectRevert(SignedCommitManager.InvalidSignature.selector); signedCommitManager.executeWithDualSignedMoves( battleKey, SWITCH_MOVE_INDEX, p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, p1Signature ); } @@ -642,16 +682,20 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); // p0's actual move data - bytes32 p0Salt = bytes32(uint256(1)); + uint104 p0Salt = uint104(1); + bytes32 p0RealMoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - // p1 signs over a DIFFERENT hash than what p0 will submit - bytes32 fakeP0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(999)), uint240(0))); + // p0 signs the commitment for the REAL move hash (matches what they'll submit) + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0RealMoveHash, battleKey, 0); - bytes memory p1Signature = _signDualReveal( - P1_PK, battleKey, 0, fakeP0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + // p1 signs over a DIFFERENT hash than what p0 will submit + bytes32 fakeP0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(999), uint16(0))); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, fakeP0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); - // p0 tries to submit with their real move data, but the hash won't match what p1 signed + // p0 tries to submit with their real move data: committer sig validates (matches + // p0RealMoveHash), but revealer sig was over fakeP0MoveHash → revealer recovery fails. vm.startPrank(p0); vm.expectRevert(SignedCommitManager.InvalidSignature.selector); signedCommitManager.executeWithDualSignedMoves( @@ -660,8 +704,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, SWITCH_MOVE_INDEX, - bytes32(0), + uint104(0), 0, + p0CommitSig, p1Signature ); } @@ -669,12 +714,13 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_revert_revealerMoveMismatch() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); // p1 signs with SWITCH_MOVE_INDEX - bytes memory p1Signature = _signDualReveal( - P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, bytes32(0), 0 + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), + P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, uint104(0), 0 ); // p0 tries to submit with different move for p1 (NO_OP instead of SWITCH) @@ -686,8 +732,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { p0Salt, 0, NO_OP_MOVE_INDEX, // Different from what p1 signed! - bytes32(0), + uint104(0), 0, + p0CommitSig, p1Signature ); } @@ -700,11 +747,11 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); // Turn 0: p0 is committer, p1 is revealer - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); // p0 signs their commitment - bytes memory p0CommitSig = _signCommit(P0_PK, p0MoveHash, battleKey, 0); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); // p1 (revealer) publishes p0's commitment on-chain vm.startPrank(p1); @@ -716,7 +763,7 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { assertEq(storedTurnId, 0, "Turn ID not stored correctly"); // Now p1 can reveal normally - signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), 0, false); // p0 reveals to complete the turn vm.startPrank(p0); @@ -733,11 +780,11 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { _completeTurnNormal(battleKey, 0); // Turn 1: p1 is committer, p0 is revealer - bytes32 p1Salt = bytes32(uint256(2)); - bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint240(0))); + uint104 p1Salt = uint104(2); + bytes32 p1MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p1Salt, uint16(0))); // p1 signs their commitment - bytes memory p1CommitSig = _signCommit(P1_PK, p1MoveHash, battleKey, 1); + bytes memory p1CommitSig = _signCommit(address(signedCommitManager), P1_PK, p1MoveHash, battleKey, 1); // p0 (revealer) publishes p1's commitment on-chain vm.startPrank(p0); @@ -749,7 +796,7 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { assertEq(storedTurnId, 1, "Turn ID not stored correctly"); // Now p0 can reveal - signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0, false); // p1 reveals to complete the turn vm.startPrank(p1); @@ -761,9 +808,9 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_anyoneCanSubmit() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); - bytes memory p0CommitSig = _signCommit(P0_PK, p0MoveHash, battleKey, 0); + uint104 p0Salt = uint104(1); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); // Even p0 themselves can submit their own signed commitment // (though this is equivalent to just calling commitMove) @@ -778,10 +825,10 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_revert_wrongSigner() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); // p1 signs instead of p0 (wrong signer) - bytes memory wrongSig = _signCommit(P1_PK, p0MoveHash, battleKey, 0); + bytes memory wrongSig = _signCommit(address(signedCommitManager), P1_PK, p0MoveHash, battleKey, 0); vm.startPrank(p1); vm.expectRevert(SignedCommitManager.InvalidSignature.selector); @@ -791,10 +838,10 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_revert_wrongTurn() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); // p0 signs for turn 1 instead of turn 0 - bytes memory wrongTurnSig = _signCommit(P0_PK, p0MoveHash, battleKey, 1); + bytes memory wrongTurnSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 1); vm.startPrank(p1); vm.expectRevert(SignedCommitManager.InvalidSignature.selector); @@ -805,10 +852,10 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { bytes32 battleKey1 = _startBattleWith(address(signedCommitManager)); bytes32 battleKey2 = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); // p0 signs for battle 1 - bytes memory battle1Sig = _signCommit(P0_PK, p0MoveHash, battleKey1, 0); + bytes memory battle1Sig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey1, 0); // Try to use on battle 2 vm.startPrank(p1); @@ -819,8 +866,8 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_revert_alreadyCommitted() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); - bytes memory p0CommitSig = _signCommit(P0_PK, p0MoveHash, battleKey, 0); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); // First commit succeeds vm.startPrank(p1); @@ -833,8 +880,8 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_revert_battleNotStarted() public { bytes32 fakeBattleKey = bytes32(uint256(123)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); - bytes memory p0CommitSig = _signCommit(P0_PK, p0MoveHash, fakeBattleKey, 0); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, fakeBattleKey, 0); vm.startPrank(p1); vm.expectRevert(DefaultCommitManager.BattleNotYetStarted.selector); @@ -844,14 +891,14 @@ contract SignedCommitManagerTest is SignedCommitManagerTestBase { function test_commitWithSignature_afterNormalCommit_reverts() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); // p0 commits normally vm.startPrank(p0); signedCommitManager.commitMove(battleKey, p0MoveHash); // Now trying to commit with signature should fail - bytes memory p0CommitSig = _signCommit(P0_PK, p0MoveHash, battleKey, 0); + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); vm.startPrank(p1); vm.expectRevert(DefaultCommitManager.AlreadyCommited.selector); signedCommitManager.commitWithSignature(battleKey, p0MoveHash, p0CommitSig); @@ -873,19 +920,21 @@ contract SignedCommitManagerEngineSafetyTest is SignedCommitManagerTestBase { bytes32 battleKey, uint64 turnId, uint8 committerMoveIndex, - uint240 committerExtraData, + uint16 committerExtraData, uint8 revealerMoveIndex, - uint240 revealerExtraData + uint16 revealerExtraData ) internal { - bytes32 committerSalt = bytes32(uint256(turnId + 1)); - bytes32 revealerSalt = bytes32(uint256(turnId + 2)); + uint104 committerSalt = uint104(turnId + 1); + uint104 revealerSalt = uint104(turnId + 2); bytes32 committerMoveHash = keccak256(abi.encodePacked(committerMoveIndex, committerSalt, committerExtraData)); // Committer is p0 on even turns, p1 on odd turns. - (uint256 revealerPk, address committerAddr) = turnId % 2 == 0 ? (P1_PK, p0) : (P0_PK, p1); + (uint256 committerPk, uint256 revealerPk, address committerAddr) = + turnId % 2 == 0 ? (P0_PK, P1_PK, p0) : (P1_PK, P0_PK, p1); - bytes memory revealerSig = _signDualReveal( + bytes memory committerSig = _signCommit(address(signedCommitManager), committerPk, committerMoveHash, battleKey, turnId); + bytes memory revealerSig = _signDualReveal(address(signedCommitManager), revealerPk, battleKey, turnId, committerMoveHash, revealerMoveIndex, revealerSalt, revealerExtraData ); @@ -898,6 +947,7 @@ contract SignedCommitManagerEngineSafetyTest is SignedCommitManagerTestBase { revealerMoveIndex, revealerSalt, revealerExtraData, + committerSig, revealerSig ); vm.stopPrank(); @@ -911,7 +961,7 @@ contract SignedCommitManagerEngineSafetyTest is SignedCommitManagerTestBase { // p0 sends a valid switch to mon 1, p1 sends NO_OP (would have been rejected at reveal in // the old flow). Engine must force p1 to switch-to-mon-0. - _executeDualSigned(battleKey, 0, SWITCH_MOVE_INDEX, uint240(1), NO_OP_MOVE_INDEX, 0); + _executeDualSigned(battleKey, 0, SWITCH_MOVE_INDEX, uint16(1), NO_OP_MOVE_INDEX, 0); assertEq(engine.getTurnIdForBattleState(battleKey), 1, "turn should advance"); uint256[] memory active = engine.getActiveMonIndexForBattleState(battleKey); @@ -971,7 +1021,7 @@ contract SignedCommitManagerEngineSafetyTest is SignedCommitManagerTestBase { // Turn 1: p1 commits SWITCH with an out-of-bounds target (team size is 2, submit 99). // p0 NO_OPs. p1's active mon should stay at 0 (switch is a no-op), not wrap to 99 & 0xFF. - _executeDualSigned(battleKey, 1, SWITCH_MOVE_INDEX, uint240(99), NO_OP_MOVE_INDEX, 0); + _executeDualSigned(battleKey, 1, SWITCH_MOVE_INDEX, uint16(99), NO_OP_MOVE_INDEX, 0); assertEq(engine.getTurnIdForBattleState(battleKey), 2, "turn should advance"); uint256[] memory active = engine.getActiveMonIndexForBattleState(battleKey); @@ -983,7 +1033,7 @@ contract SignedCommitManagerEngineSafetyTest is SignedCommitManagerTestBase { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); // Turn 0: p0 switches to mon 1, p1 to mon 0. - _executeDualSigned(battleKey, 0, SWITCH_MOVE_INDEX, uint240(1), SWITCH_MOVE_INDEX, 0); + _executeDualSigned(battleKey, 0, SWITCH_MOVE_INDEX, uint16(1), SWITCH_MOVE_INDEX, 0); assertEq(engine.getActiveMonIndexForBattleState(battleKey)[0], 1); // Turn 1: p1 is committer. p1 tries to switch to their own active mon (0). p0 NO_OP. diff --git a/test/SignedCommitManagerGasBenchmark.t.sol b/test/SignedCommitManagerGasBenchmark.t.sol index 811bbc60..06a732c3 100644 --- a/test/SignedCommitManagerGasBenchmark.t.sol +++ b/test/SignedCommitManagerGasBenchmark.t.sol @@ -26,7 +26,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { function test_gasBenchmark_normalFlow_cold() public { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); vm.startPrank(p0); uint256 gasBefore = gasleft(); @@ -35,12 +35,12 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { vm.startPrank(p1); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), 0, false); gasUsed_normalFlow_cold_reveal1 = gasBefore - gasleft(); vm.startPrank(p0); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, bytes32(uint256(1)), 0, true); + signedCommitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(1), 0, true); gasUsed_normalFlow_cold_reveal2 = gasBefore - gasleft(); emit log_named_uint("Normal Flow (Cold) - Commit (Alice)", gasUsed_normalFlow_cold_commit); @@ -55,12 +55,13 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { bytes32 battleKey = _startBattleWith(address(signedCommitManager)); // Prepare move data - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p1Salt = bytes32(uint256(2)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + uint104 p1Salt = uint104(2); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - // p1 (revealer) signs their move + p0's hash - bytes memory p1Signature = _signDualReveal( + // Both players sign off-chain + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), P1_PK, battleKey, 0, p0MoveHash, SWITCH_MOVE_INDEX, p1Salt, 0 ); @@ -75,6 +76,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { SWITCH_MOVE_INDEX, p1Salt, 0, + p0CommitSig, p1Signature ); gasUsed_dualSignedFlow_cold = gasBefore - gasleft(); @@ -90,7 +92,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { _completeTurnNormal(battleKey, 1); // Turn 2 (warm storage - p0 commits again) - bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, bytes32(uint256(100)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, uint104(100), uint16(0))); vm.startPrank(p0); uint256 gasBefore = gasleft(); @@ -99,12 +101,12 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { vm.startPrank(p1); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, uint104(0), 0, false); gasUsed_normalFlow_warm_reveal1 = gasBefore - gasleft(); vm.startPrank(p0); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, bytes32(uint256(100)), 0, true); + signedCommitManager.revealMove(battleKey, NO_OP_MOVE_INDEX, uint104(100), 0, true); gasUsed_normalFlow_warm_reveal2 = gasBefore - gasleft(); emit log_named_uint("Normal Flow (Warm) - Commit (Alice)", gasUsed_normalFlow_warm_commit); @@ -122,11 +124,12 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { _completeTurnNormal(battleKey, 1); // Turn 2 with dual-signed flow (warm storage) - bytes32 p0Salt = bytes32(uint256(100)); - bytes32 p1Salt = bytes32(uint256(101)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(100); + uint104 p1Salt = uint104(101); + bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint16(0))); - bytes memory p1Signature = _signDualReveal( + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey, 2); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), P1_PK, battleKey, 2, p0MoveHash, NO_OP_MOVE_INDEX, p1Salt, 0 ); @@ -140,6 +143,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { NO_OP_MOVE_INDEX, p1Salt, 0, + p0CommitSig, p1Signature ); gasUsed_dualSignedFlow_warm = gasBefore - gasleft(); @@ -156,7 +160,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { // Normal flow cold (3 TXs) { - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, bytes32(uint256(1)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, uint104(1), uint16(0))); vm.startPrank(p0); uint256 gasBefore = gasleft(); @@ -165,12 +169,12 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { vm.startPrank(p1); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey1, SWITCH_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey1, SWITCH_MOVE_INDEX, uint104(0), 0, false); gasUsed_normalFlow_cold_reveal1 = gasBefore - gasleft(); vm.startPrank(p0); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey1, SWITCH_MOVE_INDEX, bytes32(uint256(1)), 0, true); + signedCommitManager.revealMove(battleKey1, SWITCH_MOVE_INDEX, uint104(1), 0, true); gasUsed_normalFlow_cold_reveal2 = gasBefore - gasleft(); } @@ -178,11 +182,12 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { // Reset transient first so a stale execute from battleKey1 above doesn't pollute battleKey2's measurement. engine.resetCallContext(); { - bytes32 p0Salt = bytes32(uint256(1)); - bytes32 p1Salt = bytes32(uint256(2)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(1); + uint104 p1Salt = uint104(2); + bytes32 p0MoveHash = keccak256(abi.encodePacked(SWITCH_MOVE_INDEX, p0Salt, uint16(0))); - bytes memory p1Signature = _signDualReveal( + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey2, 0); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), P1_PK, battleKey2, 0, p0MoveHash, SWITCH_MOVE_INDEX, p1Salt, 0 ); @@ -196,6 +201,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { SWITCH_MOVE_INDEX, p1Salt, 0, + p0CommitSig, p1Signature ); gasUsed_dualSignedFlow_cold = gasBefore - gasleft(); @@ -210,7 +216,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { // Normal flow warm (turn 2) { - bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, bytes32(uint256(100)), uint240(0))); + bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, uint104(100), uint16(0))); vm.startPrank(p0); uint256 gasBefore = gasleft(); @@ -219,22 +225,23 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { vm.startPrank(p1); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey1, NO_OP_MOVE_INDEX, bytes32(0), 0, false); + signedCommitManager.revealMove(battleKey1, NO_OP_MOVE_INDEX, uint104(0), 0, false); gasUsed_normalFlow_warm_reveal1 = gasBefore - gasleft(); vm.startPrank(p0); gasBefore = gasleft(); - signedCommitManager.revealMove(battleKey1, NO_OP_MOVE_INDEX, bytes32(uint256(100)), 0, true); + signedCommitManager.revealMove(battleKey1, NO_OP_MOVE_INDEX, uint104(100), 0, true); gasUsed_normalFlow_warm_reveal2 = gasBefore - gasleft(); } // Dual-signed flow warm (turn 2) { - bytes32 p0Salt = bytes32(uint256(100)); - bytes32 p1Salt = bytes32(uint256(101)); - bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint240(0))); + uint104 p0Salt = uint104(100); + uint104 p1Salt = uint104(101); + bytes32 p0MoveHash = keccak256(abi.encodePacked(NO_OP_MOVE_INDEX, p0Salt, uint16(0))); - bytes memory p1Signature = _signDualReveal( + bytes memory p0CommitSig = _signCommit(address(signedCommitManager), P0_PK, p0MoveHash, battleKey2, 2); + bytes memory p1Signature = _signDualReveal(address(signedCommitManager), P1_PK, battleKey2, 2, p0MoveHash, NO_OP_MOVE_INDEX, p1Salt, 0 ); @@ -248,6 +255,7 @@ contract SignedCommitManagerGasBenchmarkTest is SignedCommitManagerTestBase { NO_OP_MOVE_INDEX, p1Salt, 0, + p0CommitSig, p1Signature ); gasUsed_dualSignedFlow_warm = gasBefore - gasleft(); diff --git a/test/StandardAttackPvPGasTest.sol b/test/StandardAttackPvPGasTest.sol index 27fda2a1..a0d2e1b0 100644 --- a/test/StandardAttackPvPGasTest.sol +++ b/test/StandardAttackPvPGasTest.sol @@ -14,7 +14,7 @@ import {SignedMatchmaker} from "../src/matchmaker/SignedMatchmaker.sol"; import {BattleOfferLib} from "../src/matchmaker/BattleOfferLib.sol"; import {StandardAttackFactory} from "../src/moves/StandardAttackFactory.sol"; import {ATTACK_PARAMS} from "../src/moves/StandardAttackStructs.sol"; -import {EIP712} from "../src/lib/EIP712.sol"; +import {SignedCommitHelper} from "./abstract/SignedCommitHelper.sol"; import {IEngine} from "../src/IEngine.sol"; import {IEngineHook} from "../src/IEngineHook.sol"; @@ -38,7 +38,7 @@ import {TestTeamRegistry} from "./mocks/TestTeamRegistry.sol"; /// Existing PvP benchmarks (FullyOptimizedInlineGasTest) use CustomAttack / /// EffectAttack / StatBoostsMove — none of which extend StandardAttack — so the /// StandardAttack hot path doesn't show up there. -contract StandardAttackPvPGasTest is Test, EIP712 { +contract StandardAttackPvPGasTest is SignedCommitHelper { uint256 constant MONS_PER_TEAM = 4; uint256 constant MOVES_PER_MON = 4; @@ -55,10 +55,6 @@ contract StandardAttackPvPGasTest is Test, EIP712 { TestTeamRegistry defaultRegistry; StandardAttackFactory attackFactory; - function _domainNameAndVersion() internal pure override returns (string memory, string memory) { - return ("SignedCommitManager", "1"); - } - function setUp() public { p0 = vm.addr(P0_PK); p1 = vm.addr(P1_PK); @@ -116,54 +112,22 @@ contract StandardAttackPvPGasTest is Test, EIP712 { return battleKey; } - function _signDualReveal( - uint256 privateKey, - bytes32 battleKey, - uint64 turnId, - bytes32 committerMoveHash, - uint8 revealerMoveIndex, - bytes32 revealerSalt, - uint240 revealerExtraData - ) internal view returns (bytes memory) { - bytes32 domainSeparator = keccak256( - abi.encode( - _DOMAIN_TYPEHASH, - keccak256("SignedCommitManager"), - keccak256("1"), - block.chainid, - address(signedCommitManager) - ) - ); - bytes32 structHash = SignedCommitLib.hashDualSignedReveal( - SignedCommitLib.DualSignedReveal({ - battleKey: battleKey, - turnId: turnId, - committerMoveHash: committerMoveHash, - revealerMoveIndex: revealerMoveIndex, - revealerSalt: revealerSalt, - revealerExtraData: revealerExtraData - }) - ); - bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - return abi.encodePacked(r, s, v); - } - function _fastTurn( bytes32 battleKey, uint8 p0MoveIndex, uint8 p1MoveIndex, - uint240 p0ExtraData, - uint240 p1ExtraData + uint16 p0ExtraData, + uint16 p1ExtraData ) internal { uint64 turnId = uint64(engine.getTurnIdForBattleState(battleKey)); - bytes32 committerSalt = keccak256(abi.encode("committer", battleKey, turnId)); - bytes32 revealerSalt = keccak256(abi.encode("revealer", battleKey, turnId)); + uint104 committerSalt = uint104(uint256(keccak256(abi.encode("committer", battleKey, turnId)))); + uint104 revealerSalt = uint104(uint256(keccak256(abi.encode("revealer", battleKey, turnId)))); uint8 committerMoveIndex; - uint240 committerExtraData; + uint16 committerExtraData; uint8 revealerMoveIndex; - uint240 revealerExtraData; + uint16 revealerExtraData; + uint256 committerPk; uint256 revealerPk; address committer; @@ -172,6 +136,7 @@ contract StandardAttackPvPGasTest is Test, EIP712 { committerExtraData = p0ExtraData; revealerMoveIndex = p1MoveIndex; revealerExtraData = p1ExtraData; + committerPk = P0_PK; revealerPk = P1_PK; committer = p0; } else { @@ -179,14 +144,17 @@ contract StandardAttackPvPGasTest is Test, EIP712 { committerExtraData = p1ExtraData; revealerMoveIndex = p0MoveIndex; revealerExtraData = p0ExtraData; + committerPk = P1_PK; revealerPk = P0_PK; committer = p1; } bytes32 committerMoveHash = keccak256(abi.encodePacked(committerMoveIndex, committerSalt, committerExtraData)); + address mgr = address(signedCommitManager); + bytes memory committerSig = _signCommit(mgr, committerPk, committerMoveHash, battleKey, turnId); bytes memory revealerSig = _signDualReveal( - revealerPk, battleKey, turnId, committerMoveHash, revealerMoveIndex, revealerSalt, revealerExtraData + mgr, revealerPk, battleKey, turnId, committerMoveHash, revealerMoveIndex, revealerSalt, revealerExtraData ); vm.prank(committer); @@ -198,6 +166,7 @@ contract StandardAttackPvPGasTest is Test, EIP712 { revealerMoveIndex, revealerSalt, revealerExtraData, + committerSig, revealerSig ); engine.resetCallContext(); @@ -280,7 +249,7 @@ contract StandardAttackPvPGasTest is Test, EIP712 { // Turn 0: lead-in switch. vm.startSnapshotGas("Turn0_Lead"); - _fastTurn(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _fastTurn(battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); uint256 turn0 = vm.stopSnapshotGas("Turn0_Lead"); // Turns 1-4: pure damage trades. Both players use move 0 / move 1 alternately. diff --git a/test/abstract/BattleHelper.sol b/test/abstract/BattleHelper.sol index 45caac16..c32d6a3d 100644 --- a/test/abstract/BattleHelper.sol +++ b/test/abstract/BattleHelper.sol @@ -25,10 +25,10 @@ abstract contract BattleHelper is Test { bytes32 battleKey, uint8 aliceMoveIndex, uint8 bobMoveIndex, - uint240 aliceExtraData, - uint240 bobExtraData + uint16 aliceExtraData, + uint16 bobExtraData ) internal { - bytes32 salt = ""; + uint104 salt = 0; bytes32 aliceMoveHash = keccak256(abi.encodePacked(aliceMoveIndex, salt, aliceExtraData)); bytes32 bobMoveHash = keccak256(abi.encodePacked(bobMoveIndex, salt, bobExtraData)); // Decide which player commits @@ -64,8 +64,8 @@ abstract contract BattleHelper is Test { DefaultCommitManager commitManager, bytes32 battleKey, uint8 moveIndex, - bytes32 salt, - uint240 extraData + uint104 salt, + uint16 extraData ) internal { commitManager.revealMove(battleKey, moveIndex, salt, extraData, true); vm.stopPrank(); @@ -170,4 +170,19 @@ abstract contract BattleHelper is Test { ability: 0 }); } + + /// @dev Layout used by `test/mocks/StatBoostsMove.sol`: + /// `[boostAmount:8 (signed) | statIndex:4 | monIndex:3 | playerIndex:1]` + function _packStatBoost(uint256 playerIndex, uint256 monIndex, uint256 statIndex, int32 boostAmount) + internal + pure + returns (uint16) + { + return uint16( + (playerIndex & 0x1) + | ((monIndex & 0x7) << 1) + | ((statIndex & 0xF) << 4) + | ((uint256(uint8(int8(boostAmount))) & 0xFF) << 8) + ); + } } diff --git a/test/abstract/SignedCommitHelper.sol b/test/abstract/SignedCommitHelper.sol new file mode 100644 index 00000000..5193f7c5 --- /dev/null +++ b/test/abstract/SignedCommitHelper.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity ^0.8.0; + +import {SignedCommitLib} from "../../src/commit-manager/SignedCommitLib.sol"; + +import {Test} from "forge-std/Test.sol"; + +/// @notice EIP-712 signing helpers for `SignedCommitManager` tests. +/// @dev Standalone (not inheriting `EIP712`) — replicates `_DOMAIN_TYPEHASH` to avoid pulling +/// the production base into test contracts. The verifying-contract address is taken as a +/// parameter so a single helper instance can sign for multiple managers. +abstract contract SignedCommitHelper is Test { + /// `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")` + bytes32 internal constant _SIGNED_COMMIT_DOMAIN_TYPEHASH = + 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; + + function _signedCommitDomainSeparator(address verifyingContract) internal view returns (bytes32) { + return keccak256( + abi.encode( + _SIGNED_COMMIT_DOMAIN_TYPEHASH, + keccak256("SignedCommitManager"), + keccak256("1"), + block.chainid, + verifyingContract + ) + ); + } + + function _signCommit( + address signedCommitManagerAddr, + uint256 privateKey, + bytes32 moveHash, + bytes32 battleKey, + uint64 turnId + ) internal view returns (bytes memory) { + bytes32 structHash = SignedCommitLib.hashSignedCommit( + SignedCommitLib.SignedCommit({moveHash: moveHash, battleKey: battleKey, turnId: turnId}) + ); + bytes32 digest = keccak256( + abi.encodePacked("\x19\x01", _signedCommitDomainSeparator(signedCommitManagerAddr), structHash) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } + + function _signDualReveal( + address signedCommitManagerAddr, + uint256 privateKey, + bytes32 battleKey, + uint64 turnId, + bytes32 committerMoveHash, + uint8 revealerMoveIndex, + uint104 revealerSalt, + uint16 revealerExtraData + ) internal view returns (bytes memory) { + bytes32 structHash = SignedCommitLib.hashDualSignedReveal( + SignedCommitLib.DualSignedReveal({ + battleKey: battleKey, + turnId: turnId, + committerMoveHash: committerMoveHash, + revealerMoveIndex: revealerMoveIndex, + revealerSalt: revealerSalt, + revealerExtraData: revealerExtraData + }) + ); + bytes32 digest = keccak256( + abi.encodePacked("\x19\x01", _signedCommitDomainSeparator(signedCommitManagerAddr), structHash) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } +} diff --git a/test/effects/EffectTest.sol b/test/effects/EffectTest.sol index 95349ff6..86b657b5 100644 --- a/test/effects/EffectTest.sol +++ b/test/effects/EffectTest.sol @@ -146,7 +146,7 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks, both of them are move index 0 (do frostbite damage) @@ -237,11 +237,11 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice switches to mon index 1, Bob induces frostbite - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), 0); // Check that Alice's new mon at index 0 has taken damage assertEq(engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.Hp), -1); @@ -301,7 +301,7 @@ contract EffectTest is Test, BattleHelper { */ bytes32 battleKey = _startBattle(validatorToUse, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0)); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 0, 0, 0); assertEq(engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Stamina), -1); assertEq(engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina), 0); @@ -316,7 +316,7 @@ contract EffectTest is Test, BattleHelper { assertEq(engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Stamina), -1); // Alice is asleep, Bob does nothing, Alice switches to mon index 1, should be successful mockOracle.setRNG(1); - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0); assertEq(engine.getActiveMonIndexForBattleState(battleKey)[0], 1); } @@ -392,7 +392,7 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks, both of them are move index 0 (inflict panic) @@ -477,7 +477,7 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks, both of them are move index 0 (apply burn status) @@ -628,7 +628,7 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice and Bob both select attacks, both of them are move index 0 (apply zap status) @@ -640,14 +640,14 @@ contract EffectTest is Test, BattleHelper { assertEq(engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.Stamina), -1); // Alice uses Zap, Bob switches to mon index 1 - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, 0, uint240(1)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, 0, uint16(1)); // The move should outspeed the swap, so the swap doesn't happen // So Bob's active mon index should still be 0 assertEq(engine.getActiveMonIndexForBattleState(battleKey)[1], 0); // Alice uses slower Zap, Bob switches to mon index 1 - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, SWITCH_MOVE_INDEX, 0, uint240(1)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, SWITCH_MOVE_INDEX, 0, uint16(1)); // Bob's active mon index should be 1 (swap goes before getting Zapped) assertEq(engine.getActiveMonIndexForBattleState(battleKey)[1], 1); @@ -657,7 +657,7 @@ contract EffectTest is Test, BattleHelper { assertEq(zapEffects.length, 1); // Alice does nothing, Bob attempts to switch to mon index 1, which should succeed because Zap allows switches - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(0)); // Check that Bob's active mon index is now 0, and the effect is still there assertEq(engine.getActiveMonIndexForBattleState(battleKey)[1], 0); @@ -665,7 +665,7 @@ contract EffectTest is Test, BattleHelper { assertEq(zapEffectsAfter.length, 1); // Bob switches back to mon index 1, Alice does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(1)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(1)); // Bob tries to make a move, Alice does nothing, Zap should skip his turn _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 0, 0, 0); @@ -728,7 +728,7 @@ contract EffectTest is Test, BattleHelper { // First move of the game has to be selecting their mons (both index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses NoDamage, Bob does as well @@ -803,7 +803,7 @@ contract EffectTest is Test, BattleHelper { // First move: both switch in their mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify Bob's mon has the heal effect applied (from ability on switch in) diff --git a/test/effects/StatBoosts.t.sol b/test/effects/StatBoosts.t.sol index cb276a67..bd0de342 100644 --- a/test/effects/StatBoosts.t.sol +++ b/test/effects/StatBoosts.t.sol @@ -38,11 +38,6 @@ contract StatBoostsTest is Test, BattleHelper { StatBoostsMove statBoostMove; DefaultMatchmaker matchmaker; - // Helper to pack StatBoostsMove extraData: lower 60 bits = playerIndex, next 60 bits = monIndex, next 60 bits = statIndex, upper 60 bits = boostAmount - function _packStatBoost(uint256 playerIndex, uint256 monIndex, uint256 statIndex, int32 boostAmount) internal pure returns (uint240) { - return uint240(playerIndex | (monIndex << 60) | (statIndex << 120) | (uint256(uint32(boostAmount)) << 180)); - } - function setUp() public { typeCalc = new TestTypeCalculator(); mockOracle = new MockRandomnessOracle(); @@ -112,7 +107,7 @@ contract StatBoostsTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // We'll test Attack stat in detail @@ -193,7 +188,7 @@ contract StatBoostsTest is Test, BattleHelper { battleKey, SWITCH_MOVE_INDEX, // Alice switches NO_OP_MOVE_INDEX, // Bob does nothing - uint240(1), // Alice switches to mon 1 + uint16(1), // Alice switches to mon 1 0 // Bob does nothing ); @@ -215,7 +210,7 @@ contract StatBoostsTest is Test, BattleHelper { battleKey, SWITCH_MOVE_INDEX, // Alice switches NO_OP_MOVE_INDEX, // Bob does nothing - uint240(0), // Alice switches back to mon 0 + uint16(0), // Alice switches back to mon 0 0 // Bob does nothing ); @@ -286,7 +281,7 @@ contract StatBoostsTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Test all stats @@ -335,7 +330,7 @@ contract StatBoostsTest is Test, BattleHelper { battleKey, SWITCH_MOVE_INDEX, // Alice switches NO_OP_MOVE_INDEX, // Bob does nothing - uint240(1), // Alice switches to mon 1 + uint16(1), // Alice switches to mon 1 0 // Bob does nothing ); @@ -389,7 +384,7 @@ contract StatBoostsTest is Test, BattleHelper { // Both players select their first mon (index 0) bytes32 battleKey = _startBattle(validatorToUse, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses stat boost move to boost her mon's special atk 50%, Bob does nothing @@ -429,7 +424,7 @@ contract StatBoostsTest is Test, BattleHelper { battleKey, SWITCH_MOVE_INDEX, // Alice switches NO_OP_MOVE_INDEX, // Bob does nothing - uint240(1), // Alice switches to mon 1 + uint16(1), // Alice switches to mon 1 0 // Bob does nothing ); diff --git a/test/mocks/CustomAttack.sol b/test/mocks/CustomAttack.sol index 0f5913a5..9c4a12c0 100644 --- a/test/mocks/CustomAttack.sol +++ b/test/mocks/CustomAttack.sol @@ -55,7 +55,7 @@ contract CustomAttack is IMoveSet { uint256 attackerPlayerIndex, uint256 attackerMonIndex, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 rng ) external { _standardAttack.move(engine, battleKey, attackerPlayerIndex, attackerMonIndex, defenderMonIndex, extraData, rng); @@ -73,7 +73,7 @@ contract CustomAttack is IMoveSet { return _standardAttack.moveType(engine, battleKey); } - function isValidTarget(IEngine engine, bytes32 battleKey, uint240 extraData) external view returns (bool) { + function isValidTarget(IEngine engine, bytes32 battleKey, uint16 extraData) external view returns (bool) { return _standardAttack.isValidTarget(engine, battleKey, extraData); } diff --git a/test/mocks/EditEffectAttack.sol b/test/mocks/EditEffectAttack.sol index ebcffea0..670b8601 100644 --- a/test/mocks/EditEffectAttack.sol +++ b/test/mocks/EditEffectAttack.sol @@ -13,11 +13,12 @@ contract EditEffectAttack is IMoveSet { return "Edit Effect Attack"; } - function move(IEngine engine, bytes32, uint256, uint256, uint256, uint240 extraData, uint256) external { - // Unpack extraData: lower 80 bits = targetIndex, next 80 bits = monIndex, upper 80 bits = effectIndex - uint256 targetIndex = uint256(extraData) & ((1 << 80) - 1); - uint256 monIndex = (uint256(extraData) >> 80) & ((1 << 80) - 1); - uint256 effectIndex = (uint256(extraData) >> 160) & ((1 << 80) - 1); + function move(IEngine engine, bytes32, uint256, uint256, uint256, uint16 extraData, uint256) external { + // Unpack extraData (16 bits): bits 0..1 = targetIndex (0=p0, 1=p1, 2=global), + // bits 2..5 = monIndex (max 15), bits 6..15 = effectIndex (max 1023). + uint256 targetIndex = uint256(extraData) & 0x3; + uint256 monIndex = (uint256(extraData) >> 2) & 0xF; + uint256 effectIndex = (uint256(extraData) >> 6) & 0x3FF; engine.editEffect(targetIndex, monIndex, effectIndex, bytes32(uint256(69))); } @@ -33,7 +34,7 @@ contract EditEffectAttack is IMoveSet { return Type.Fire; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/EffectAttack.sol b/test/mocks/EffectAttack.sol index fe05a28d..dcd68cd5 100644 --- a/test/mocks/EffectAttack.sol +++ b/test/mocks/EffectAttack.sol @@ -33,7 +33,7 @@ contract EffectAttack is IMoveSet { return "Effect Attack"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint16, uint256) external { uint256 targetIndex = (attackerPlayerIndex + 1) % 2; engine.addEffect(targetIndex, defenderMonIndex, EFFECT, bytes32(0)); } @@ -50,7 +50,7 @@ contract EffectAttack is IMoveSet { return TYPE; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/ForceSwitchMove.sol b/test/mocks/ForceSwitchMove.sol index 6b83b8fb..d7966f40 100644 --- a/test/mocks/ForceSwitchMove.sol +++ b/test/mocks/ForceSwitchMove.sol @@ -30,10 +30,10 @@ contract ForceSwitchMove is IMoveSet { return "Force Switch"; } - function move(IEngine engine, bytes32, uint256, uint256, uint256, uint240 extraData, uint256) external { - // Decode data as packed (playerIndex in lower 120 bits, monToSwitchIndex in upper 120 bits) - uint256 playerIndex = uint256(extraData) & ((1 << 120) - 1); - uint256 monToSwitchIndex = uint256(extraData) >> 120; + function move(IEngine engine, bytes32, uint256, uint256, uint256, uint16 extraData, uint256) external { + // Pack: bit 0 = playerIndex (0 or 1), bits 1..15 = monToSwitchIndex + uint256 playerIndex = uint256(extraData) & 0x1; + uint256 monToSwitchIndex = uint256(extraData) >> 1; // Use the new switchActiveMon function engine.switchActiveMon(playerIndex, monToSwitchIndex); @@ -51,7 +51,7 @@ contract ForceSwitchMove is IMoveSet { return TYPE; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/GlobalEffectAttack.sol b/test/mocks/GlobalEffectAttack.sol index f5be9b13..b5bcb375 100644 --- a/test/mocks/GlobalEffectAttack.sol +++ b/test/mocks/GlobalEffectAttack.sol @@ -33,7 +33,7 @@ contract GlobalEffectAttack is IMoveSet { return "Effect Attack"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256, uint16, uint256) external { engine.addEffect(2, 0, EFFECT, bytes32(attackerPlayerIndex)); } @@ -49,7 +49,7 @@ contract GlobalEffectAttack is IMoveSet { return TYPE; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/InvalidMove.sol b/test/mocks/InvalidMove.sol index 3cee3926..dadb8746 100644 --- a/test/mocks/InvalidMove.sol +++ b/test/mocks/InvalidMove.sol @@ -15,7 +15,7 @@ contract InvalidMove is IMoveSet { return "Effect Attack"; } - function move(IEngine, bytes32, uint256, uint256, uint256, uint240, uint256) external pure { + function move(IEngine, bytes32, uint256, uint256, uint256, uint16, uint256) external pure { // No-op } @@ -31,7 +31,7 @@ contract InvalidMove is IMoveSet { return Type.Fire; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return false; } diff --git a/test/mocks/MockEffectRemover.sol b/test/mocks/MockEffectRemover.sol index df30442f..61802680 100644 --- a/test/mocks/MockEffectRemover.sol +++ b/test/mocks/MockEffectRemover.sol @@ -10,8 +10,7 @@ import {IMoveSet} from "../../src/moves/IMoveSet.sol"; /** * Mock move that removes an effect from a target mon. - * The effect address to remove is passed as extraData (targetArgs). - * Targets the opponent's active mon. + * The effect's slot index is passed as extraData. Targets the opponent's active mon. */ contract MockEffectRemover is IMoveSet { @@ -25,20 +24,23 @@ contract MockEffectRemover is IMoveSet { uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, - uint240 extraData, + uint16 extraData, uint256 ) external { - // extraData contains the address of the effect to remove (packed as uint160) - address effectToRemove = address(uint160(extraData)); + // extraData is the slot index of the effect to remove (from getEffects). + uint256 slotIndex = uint256(extraData); // Target the opponent's active mon uint256 targetPlayerIndex = 1 - attackerPlayerIndex; - // Find and remove the effect (removeEffect in Engine handles calling onRemove with proper params) - (EffectInstance[] memory effects, uint256[] memory indices) = engine.getEffects(battleKey, targetPlayerIndex, defenderMonIndex); - for (uint256 i = 0; i < effects.length; i++) { - if (address(effects[i].effect) == effectToRemove) { - engine.removeEffect(targetPlayerIndex, defenderMonIndex, indices[i]); + // Verify the slot is still occupied at this index before removing + (EffectInstance[] memory effects, uint256[] memory indices) = + engine.getEffects(battleKey, targetPlayerIndex, defenderMonIndex); + for (uint256 i = 0; i < indices.length; i++) { + if (indices[i] == slotIndex) { + if (address(effects[i].effect) != address(0)) { + engine.removeEffect(targetPlayerIndex, defenderMonIndex, slotIndex); + } break; } } @@ -60,7 +62,7 @@ contract MockEffectRemover is IMoveSet { return MoveClass.Other; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/MockKVWriterMove.sol b/test/mocks/MockKVWriterMove.sol index 79640190..22222733 100644 --- a/test/mocks/MockKVWriterMove.sol +++ b/test/mocks/MockKVWriterMove.sol @@ -9,17 +9,18 @@ import {IMoveSet} from "../../src/moves/IMoveSet.sol"; import {MoveMeta} from "../../src/Structs.sol"; /// @notice Test-only move that writes a single, caller-chosen (key, value) pair to globalKV. -/// @dev extraData layout: lower 64 bits = key, upper 176 bits = value. A 0-value input -/// writes 1 by default so tests can quickly assert "something was written" without -/// encoding a non-zero value every time. +/// @dev extraData layout (16 bits total): bits 0..9 = key (≤1023), bits 10..15 = value (≤63). +/// A 0-value input writes 1 by default so tests can quickly assert "something was written" +/// without encoding a non-zero value every time. Tests that need wider key/value ranges +/// should use a different mock. contract MockKVWriterMove is IMoveSet { function name() external pure returns (string memory) { return "MockKVWriter"; } - function move(IEngine engine, bytes32, uint256, uint256, uint256, uint240 extraData, uint256) external { - uint64 key = uint64(extraData); - uint192 value = uint192(uint256(extraData) >> 64); + function move(IEngine engine, bytes32, uint256, uint256, uint256, uint16 extraData, uint256) external { + uint64 key = uint64(extraData) & 0x3FF; // 10 bits + uint192 value = uint192(uint256(extraData) >> 10); // 6 bits if (value == 0) { value = 1; } @@ -42,7 +43,7 @@ contract MockKVWriterMove is IMoveSet { return MoveClass.Self; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/ReduceSpAtkMove.sol b/test/mocks/ReduceSpAtkMove.sol index 375e51dc..b5738980 100644 --- a/test/mocks/ReduceSpAtkMove.sol +++ b/test/mocks/ReduceSpAtkMove.sol @@ -20,7 +20,7 @@ contract ReduceSpAtkMove is IMoveSet { return "Reduce SpAtk"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint16, uint256) external { // Get the opposing player's index uint256 opposingPlayerIndex = (attackerPlayerIndex + 1) % 2; @@ -40,7 +40,7 @@ contract ReduceSpAtkMove is IMoveSet { return Type.Math; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/SelfSwitchAndDamageMove.sol b/test/mocks/SelfSwitchAndDamageMove.sol index 3fb5b1d1..ac3fff8b 100644 --- a/test/mocks/SelfSwitchAndDamageMove.sol +++ b/test/mocks/SelfSwitchAndDamageMove.sol @@ -21,7 +21,7 @@ contract SelfSwitchAndDamageMove is IMoveSet { return "Self Switch And Damage Move"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint240 extraData, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint16 extraData, uint256) external { uint256 monToSwitchIndex = uint256(extraData); // Deal damage first to opponent @@ -44,7 +44,7 @@ contract SelfSwitchAndDamageMove is IMoveSet { return Type.Fire; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/SkipTurnMove.sol b/test/mocks/SkipTurnMove.sol index be9db1e1..9120f4ae 100644 --- a/test/mocks/SkipTurnMove.sol +++ b/test/mocks/SkipTurnMove.sol @@ -30,7 +30,7 @@ contract SkipTurnMove is IMoveSet { return "Skip Turn"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint16, uint256) external { uint256 targetIndex = (attackerPlayerIndex + 1) % 2; engine.updateMonState(targetIndex, defenderMonIndex, MonStateIndexName.ShouldSkipTurn, 1); } @@ -47,7 +47,7 @@ contract SkipTurnMove is IMoveSet { return TYPE; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/StatBoostsMove.sol b/test/mocks/StatBoostsMove.sol index 2b869396..4abc7544 100644 --- a/test/mocks/StatBoostsMove.sol +++ b/test/mocks/StatBoostsMove.sol @@ -22,12 +22,12 @@ contract StatBoostsMove is IMoveSet { return ""; } - function move(IEngine engine, bytes32, uint256, uint256, uint256, uint240 extraData, uint256) external { - // Unpack extraData: lower 60 bits = playerIndex, next 60 bits = monIndex, next 60 bits = statIndex, upper 60 bits = boostAmount - uint256 playerIndex = uint256(extraData) & ((1 << 60) - 1); - uint256 monIndex = (uint256(extraData) >> 60) & ((1 << 60) - 1); - uint256 statIndex = (uint256(extraData) >> 120) & ((1 << 60) - 1); - int32 boostAmount = int32(int256((uint256(extraData) >> 180) & ((1 << 60) - 1))); + function move(IEngine engine, bytes32, uint256, uint256, uint256, uint16 extraData, uint256) external { + // Unpack extraData: [boostAmount:8 | statIndex:4 | monIndex:3 | playerIndex:1] + uint256 playerIndex = uint256(extraData) & 0x1; + uint256 monIndex = (uint256(extraData) >> 1) & 0x7; + uint256 statIndex = (uint256(extraData) >> 4) & 0xF; + int32 boostAmount = int32(int8(uint8(uint256(extraData) >> 8))); // For all tests, we'll use Temp stat boosts with Multiply type for positive boosts // and Divide type for negative boosts @@ -59,7 +59,7 @@ contract StatBoostsMove is IMoveSet { return Type.Air; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mocks/TestMoveFactory.sol b/test/mocks/TestMoveFactory.sol index 230d654f..02ab8f1d 100644 --- a/test/mocks/TestMoveFactory.sol +++ b/test/mocks/TestMoveFactory.sol @@ -24,7 +24,7 @@ contract TestMove is IMoveSet { return "Test Move"; } - function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint240, uint256) external { + function move(IEngine engine, bytes32, uint256 attackerPlayerIndex, uint256, uint256 defenderMonIndex, uint16, uint256) external { uint256 opponentIndex = (attackerPlayerIndex + 1) % 2; engine.dealDamage(opponentIndex, defenderMonIndex, _damage); } @@ -41,7 +41,7 @@ contract TestMove is IMoveSet { return _moveType; } - function isValidTarget(IEngine, bytes32, uint240) external pure returns (bool) { + function isValidTarget(IEngine, bytes32, uint16) external pure returns (bool) { return true; } diff --git a/test/mons/AuroxTest.sol b/test/mons/AuroxTest.sol index 89914532..bcd566fd 100644 --- a/test/mons/AuroxTest.sol +++ b/test/mons/AuroxTest.sol @@ -87,7 +87,7 @@ contract AuroxTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Bull Rush, Bob does nothing _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); @@ -177,7 +177,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice spends 1 stamina, Bob inflicts frostbite @@ -198,7 +198,7 @@ contract AuroxTest is Test, BattleHelper { ); // Alice swaps to mon index 1, Bob does the 50% attack - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 1, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 1, uint16(1), 0); // Verify that Alice's mon index 1 has taken 50% damage int32 aliceDamage = engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.Hp); @@ -209,7 +209,7 @@ contract AuroxTest is Test, BattleHelper { ); // Alice uses Gilded Recovery targeting self, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, uint16(1), 0); // Nothing should happen, mon index 0 for Alice should still have -1 staminaDelta, hpDelta for mon index 1 should still be the same assertEq( @@ -224,7 +224,7 @@ contract AuroxTest is Test, BattleHelper { ); // Alice uses Gilded Recovery targeting mon index , Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 2, NO_OP_MOVE_INDEX, uint16(0), 0); // Verify that Alice's mon index 1 is healed by 50% and mon index 0 has staminaDelta of 0, and no longer has frostbite assertEq( @@ -293,7 +293,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Iron Wall, Bob does nothing @@ -326,7 +326,7 @@ contract AuroxTest is Test, BattleHelper { assertEq(aliceDamage, expectedDamagePerHit * 2, "Alice's mon should take reduced damage on second hit"); // Alice switches to mon index 1, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0); // Verify that the Iron Wall effect is now gone after switch out (effects, ) = engine.getEffects(battleKey, 0, 0); @@ -380,7 +380,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Iron Wall, Bob does nothing @@ -443,7 +443,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice does nothing, Bob attacks @@ -518,7 +518,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice does nothing, Bob attacks @@ -613,7 +613,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses attack, Bob does nothing @@ -624,7 +624,7 @@ contract AuroxTest is Test, BattleHelper { assertEq(bobAttackDelta, int32(int8(upOnly.ATTACK_BOOST_PERCENT())) * int32(maxHp) / 100, "Bob's mon should be boosted"); // Alice does nothing, Bob switches to mon index 1 - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(1)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(1)); // Verify that Bob's mon index 0 has a positive attack delta of upOnly.ATTACK_BOOST_PERCENT() bobAttackDelta = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Attack); @@ -699,7 +699,7 @@ contract AuroxTest is Test, BattleHelper { // Turn 0: Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Turn 1: Alice does nothing, Bob attacks Alice @@ -760,7 +760,7 @@ contract AuroxTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Set rng to be 2 to trigger frostbite diff --git a/test/mons/EkinekiTest.sol b/test/mons/EkinekiTest.sol index 7a4315fd..9bcca4ab 100644 --- a/test/mons/EkinekiTest.sol +++ b/test/mons/EkinekiTest.sol @@ -121,7 +121,7 @@ contract EkinekiTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Bubble Bop, Bob does nothing @@ -147,7 +147,7 @@ contract EkinekiTest is Test, BattleHelper { bytes32 battleKey2 = _startBattle(validator2, engine2, mockOracle, registry2, matchmaker2, address(commitManager2)); _commitRevealExecuteForAliceAndBob( - engine2, commitManager2, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine2, commitManager2, battleKey2, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob uses single hit on Alice @@ -194,11 +194,11 @@ contract EkinekiTest is Test, BattleHelper { // Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses SneakAttack targeting Bob's non-active mon (index 1) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), 0); // Verify Bob's mon at index 1 (non-active) took damage int32 bobMon1HpDelta = engine.getMonStateForBattle(battleKey, 1, 1, MonStateIndexName.Hp); @@ -241,17 +241,17 @@ contract EkinekiTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses SneakAttack targeting Bob's non-active mon (index 1) - first use - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), 0); int32 bobMon1DamageAfterFirst = engine.getMonStateForBattle(battleKey, 1, 1, MonStateIndexName.Hp); assertTrue(bobMon1DamageAfterFirst < 0, "First sneak attack should deal damage"); // Alice uses SneakAttack again - should do nothing (already used this switch-in) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), 0); int32 bobMon1DamageAfterSecond = engine.getMonStateForBattle(battleKey, 1, 1, MonStateIndexName.Hp); assertEq( @@ -293,21 +293,21 @@ contract EkinekiTest is Test, BattleHelper { // Both players select mon 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses SneakAttack - first use works - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), 0); int32 damageAfterFirst = engine.getMonStateForBattle(battleKey, 1, 1, MonStateIndexName.Hp); assertTrue(damageAfterFirst < 0, "First sneak attack should deal damage"); // Alice switches to mon 1 (sneak attack effect removed on switch-out) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); // Alice (now mon 1) uses SneakAttack again - should work (reset by switch) - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), 0); int32 damageAfterReset = engine.getMonStateForBattle(battleKey, 1, 1, MonStateIndexName.Hp); assertTrue(damageAfterReset < damageAfterFirst, "Sneak attack should work again after switching"); } @@ -362,7 +362,7 @@ contract EkinekiTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob uses test attack without 999 (baseline) @@ -457,7 +457,7 @@ contract EkinekiTest is Test, BattleHelper { // Both select mon 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob attacks Alice's mon 0 (KO), Alice does nothing @@ -473,7 +473,7 @@ contract EkinekiTest is Test, BattleHelper { // Alice forced switch to mon 2 (the one with savior complex) // After KO, playerSwitchForTurnFlag = 0 (Alice must switch, no commit needed) vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(2), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(2), true); engine.resetCallContext(); // Verify that Alice's mon 2 got a sp atk boost (STAGE_1_BOOST = 15% of 100 = 15) int32 spAtkDelta = engine.getMonStateForBattle(battleKey, 0, 2, MonStateIndexName.SpecialAttack); @@ -556,7 +556,7 @@ contract EkinekiTest is Test, BattleHelper { // Both select mon 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob KOs Alice's mon 0 @@ -564,14 +564,14 @@ contract EkinekiTest is Test, BattleHelper { // Alice forced switch to mon 1 (savior complex triggers with 1 KO) vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), true); engine.resetCallContext(); int32 spAtkDeltaFirstSwitch = engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.SpecialAttack); assertEq(spAtkDeltaFirstSwitch, 15, "Should get 15 sp atk boost from 1 KO"); // Alice switches to mon 2, Bob KOs Alice's mon 2 in the same turn (Bob is faster but switch has higher priority) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(2), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(2), 0 ); // Verify Alice's mon 2 is KO'd @@ -583,7 +583,7 @@ contract EkinekiTest is Test, BattleHelper { // Alice forced switch back to mon 1 (savior complex should NOT trigger again) vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), true); engine.resetCallContext(); int32 spAtkDeltaSecondSwitch = engine.getMonStateForBattle(battleKey, 0, 1, MonStateIndexName.SpecialAttack); // Boost is temp so it was cleared when mon 1 switched out, and savior complex @@ -665,7 +665,7 @@ contract EkinekiTest is Test, BattleHelper { // Alice selects mon 0 (with savior complex) - no KO'd mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify no boost was applied (0 KOs) @@ -682,7 +682,7 @@ contract EkinekiTest is Test, BattleHelper { // Alice forced switch to mon 1 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(1), true); engine.resetCallContext(); // Mon 1 has no ability, so no savior complex trigger // But the savior complex on mon 0 should NOT have been consumed (it didn't trigger) @@ -720,7 +720,7 @@ contract EkinekiTest is Test, BattleHelper { _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Overflow, Bob does nothing diff --git a/test/mons/EmbursaTest.sol b/test/mons/EmbursaTest.sol index e80a42df..d5dae67c 100644 --- a/test/mons/EmbursaTest.sol +++ b/test/mons/EmbursaTest.sol @@ -94,12 +94,12 @@ contract EmbursaTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Q5, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Verify no damage occurred @@ -110,7 +110,7 @@ contract EmbursaTest is Test, BattleHelper { // Wait 4 turns for (uint256 i = 0; i < 4; i++) { _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); } // Verify no damage occurred @@ -123,7 +123,7 @@ contract EmbursaTest is Test, BattleHelper { // Alice and Bob both do nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Verify damage occurred @@ -226,7 +226,7 @@ contract EmbursaTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); (EffectInstance[] memory effects, ) = engine.getEffects(battleKey, 1, 0); @@ -259,7 +259,7 @@ contract EmbursaTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); (effects, ) = engine.getEffects(battleKey, 1, 0); assertEq(effects.length, 0, "Bob's mon should have no effects"); @@ -276,7 +276,7 @@ contract EmbursaTest is Test, BattleHelper { // Verify Q5 was applied to global effects, verify Alice is KOed battleKey = _startBattle(validatorToUse, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, 4, 0, 0); @@ -295,7 +295,7 @@ contract EmbursaTest is Test, BattleHelper { // Verify Honey Bribe applied stat boost to Bob's mon, verify Alice is KOed battleKey = _startBattle(validatorToUse, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 3, 4, 0, 0); @@ -372,7 +372,7 @@ contract EmbursaTest is Test, BattleHelper { // Both switch in _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Q5, Bob does nothing @@ -381,7 +381,7 @@ contract EmbursaTest is Test, BattleHelper { // Wait 4 turns (Q5 counter ticks from 1 to 5) for (uint256 i = 0; i < 4; i++) { _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); } @@ -469,7 +469,7 @@ contract EmbursaTest is Test, BattleHelper { vm.warp(vm.getBlockTimestamp() + 1); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Set RNG so that burn triggers (rng % 3 == 2) @@ -555,7 +555,7 @@ contract EmbursaTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validatorToUse, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob uses burn attack on Alice (Bob is faster) diff --git a/test/mons/GhouliathTest.sol b/test/mons/GhouliathTest.sol index 2a12be8d..c94c1ce6 100644 --- a/test/mons/GhouliathTest.sol +++ b/test/mons/GhouliathTest.sol @@ -150,7 +150,7 @@ contract GhouliathTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob uses the attack (which KOs) on Alice's mon @@ -170,7 +170,7 @@ contract GhouliathTest is Test, BattleHelper { // Alice swaps in mon index 1 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // We wait for the REVIVAL_DELAY - 1 turns to pass for (uint256 i = 0; i < riseFromTheGrave.REVIVAL_DELAY() - 1; i++) { @@ -188,12 +188,12 @@ contract GhouliathTest is Test, BattleHelper { assertEq(damageTaken, -99, "Alice's mon should have 1 HP"); // Alice swaps in mon index 0, Bob does attack again, which KOs Alice's mon - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, 0, uint16(0), 0); // Verify the mon is not revived after REVIVAL_DELAY turns // (First we swap in mon index 1) vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); for (uint256 i = 0; i < riseFromTheGrave.REVIVAL_DELAY() - 1; i++) { _commitRevealExecuteForAliceAndBob( @@ -256,7 +256,7 @@ contract GhouliathTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob uses the attack (which KOs) on Alice's mon @@ -264,14 +264,14 @@ contract GhouliathTest is Test, BattleHelper { // Alice swaps in mon index 1 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice KOs Bob's mon _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, 0, 0); // Bob swaps in mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // We wait for the REVIVAL_DELAY turns to pass for (uint256 i = 0; i < riseFromTheGrave.REVIVAL_DELAY() - 1; i++) { @@ -346,7 +346,7 @@ contract GhouliathTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses WitherAway on Bob's mon @@ -448,7 +448,7 @@ contract GhouliathTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Osteoporosis on Bob's mon @@ -500,12 +500,12 @@ contract GhouliathTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice does nothing, Bob switches to mon index 1 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(1) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(1) ); // Alice uses Eternal Grudge on Bob's mon diff --git a/test/mons/GorillaxTest.sol b/test/mons/GorillaxTest.sol index 8373d33d..9093a41f 100644 --- a/test/mons/GorillaxTest.sol +++ b/test/mons/GorillaxTest.sol @@ -97,7 +97,7 @@ contract GorillaxTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice chooses to attack, Bob chooses to do nothing for CHARGE_COUNT rounds @@ -168,12 +168,12 @@ contract GorillaxTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Rock Pull, Bob switches to mon index 1 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, uint240(0), uint240(1) + engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, uint16(0), uint16(1) ); // Assert that Bob's mon index 0 took damage @@ -184,7 +184,7 @@ contract GorillaxTest is Test, BattleHelper { // Alice uses Rock Pull, Bob does not switch _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Assert that Alice's mon index 0 took damage diff --git a/test/mons/IblivionTest.sol b/test/mons/IblivionTest.sol index 56fcb7d9..e8bd5659 100644 --- a/test/mons/IblivionTest.sol +++ b/test/mons/IblivionTest.sol @@ -112,7 +112,7 @@ contract IblivionTest is Test, BattleHelper { // Switch in mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Check that Baselight level is 2 (1 from switch-in + 1 from round end) @@ -153,7 +153,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Baselight starts at 2 (1 from switch + 1 from round end) @@ -227,7 +227,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice starts with 2 Baselight stacks (1 from switch + 1 from round end) @@ -292,7 +292,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // No Baselight stacks @@ -370,7 +370,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice has 2 stacks (not 3), so normal power (80) @@ -441,7 +441,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Wait for 3 stacks (start at 2, need 1 more round) @@ -500,7 +500,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // At Baselight 2, Loop should give 30% boost @@ -555,7 +555,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Loop first time @@ -611,7 +611,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Wait for 3 stacks (start at 2, need 1 more round) @@ -666,7 +666,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Start at 2 stacks (1 initial + 1 from round end) @@ -714,7 +714,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Loop to get stat boosts @@ -767,7 +767,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Loop @@ -847,7 +847,7 @@ contract IblivionTest is Test, BattleHelper { bytes32 battleKey = _startBattle(validator, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Check priority @@ -945,7 +945,7 @@ contract IblivionTest is Test, BattleHelper { // Switch in mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify Alice's attack starts at base (0 delta) @@ -994,10 +994,20 @@ contract IblivionTest is Test, BattleHelper { } assertTrue(stillHasBurn, "Alice should still have burn effect after Renormalize"); - // Bob uses MockEffectRemover to remove burn from Alice (move index 1) - // Pass burn status address as extraData + // Bob uses MockEffectRemover to remove burn from Alice (move index 1). + // Pass burn status's slot index as extraData (looked up from Alice's effects). + uint16 burnSlot; + { + (EffectInstance[] memory beforeRemove, uint256[] memory beforeIndices) = engine.getEffects(battleKey, 0, 0); + for (uint256 i = 0; i < beforeRemove.length; i++) { + if (address(beforeRemove[i].effect) == address(burnStatus)) { + burnSlot = uint16(beforeIndices[i]); + break; + } + } + } _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 1, 0, uint240(uint160(address(burnStatus))) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 1, 0, burnSlot ); // Verify burn effect is removed diff --git a/test/mons/InutiaTest.sol b/test/mons/InutiaTest.sol index 57434918..8c1f37a0 100644 --- a/test/mons/InutiaTest.sol +++ b/test/mons/InutiaTest.sol @@ -112,7 +112,7 @@ contract InutiaTest is Test, BattleHelper { // First move: Alice switches to the mon with Interweaving ability, Bob switches to the other mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(1), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(1), uint16(0) ); // Check that Bob's mon Attack stat has been decreased @@ -124,7 +124,7 @@ contract InutiaTest is Test, BattleHelper { // Alice switches back to the regular mon, Bob does a No-Op _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); // Check that Bob's mon SpecialAttack stat has been decreased @@ -177,7 +177,7 @@ contract InutiaTest is Test, BattleHelper { // Send in mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both players select move index 0 @@ -205,7 +205,7 @@ contract InutiaTest is Test, BattleHelper { // Now both players swap to mon index 1 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(1), uint240(1) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(1), uint16(1) ); // The stat boost should carry over @@ -220,7 +220,7 @@ contract InutiaTest is Test, BattleHelper { // Now both players swap back to mon index 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both players select move index 0 @@ -326,7 +326,7 @@ contract InutiaTest is Test, BattleHelper { bytes32 battleKey = _startBattle(v, engine, mockOracle, defaultRegistry, matchmaker, address(commitManager)); _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses CE, Bob does nothing (turn 1) @@ -339,7 +339,7 @@ contract InutiaTest is Test, BattleHelper { // Bob swaps to mon index 1 (turn 3) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(1) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(1) ); // Verify damage dealt to Bob's mon index 1 is 1/16 of max HP (charge 1) @@ -348,7 +348,7 @@ contract InutiaTest is Test, BattleHelper { // Bob swaps to mon index 2 (turn 4) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(2) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(2) ); // Verify damage dealt to Bob's mon index 2 is 1/4 of max HP (charge 2) @@ -357,7 +357,7 @@ contract InutiaTest is Test, BattleHelper { // Bob swaps back to mon index 0 (turn 5) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(0) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(0) ); // Verify damage dealt to Bob's mon index 0 is 1/8 of max HP (charge 3) @@ -366,7 +366,7 @@ contract InutiaTest is Test, BattleHelper { // Bob swaps to mon index 1 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint240(1) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, 0, uint16(1) ); // Verify damage dealt to Bob's mon index 1 is 1/16 of max HP (charge 4) @@ -391,12 +391,12 @@ contract InutiaTest is Test, BattleHelper { // Alice swaps to mon index 1, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); // Alice swaps back to mon index 0, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); // Verify Alice's mon index 0 is healed by 1/16 of max HP diff --git a/test/mons/MalalienTest.sol b/test/mons/MalalienTest.sol index 63557fbb..569b76d6 100644 --- a/test/mons/MalalienTest.sol +++ b/test/mons/MalalienTest.sol @@ -129,7 +129,7 @@ contract MalalienTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice's mon has ActusReus ability @@ -153,7 +153,7 @@ contract MalalienTest is Test, BattleHelper { // Bob switches to mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice does nothing, Bob attacks and KOs Alice's mon _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, NO_OP_MOVE_INDEX, 0, 0, 0); @@ -208,11 +208,11 @@ contract MalalienTest is Test, BattleHelper { // Alice and Bob both send in mon index 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both players use triple think - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 0, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 0, uint16(0), uint16(0)); // SpecialAttack delta for both is 100 int32 aliceSpAtkBoost = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.SpecialAttack); @@ -223,7 +223,7 @@ contract MalalienTest is Test, BattleHelper { // Alice uses it again, Bob swaps out _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, uint240(0), uint240(1) + engine, commitManager, battleKey, 0, SWITCH_MOVE_INDEX, uint16(0), uint16(1) ); // Alice should be at 1.75 * 1.75 = 1.225 + 1.75 + 0.0875 = 2.0625, Bob should be at 0 diff --git a/test/mons/PengymTest.sol b/test/mons/PengymTest.sol index 6346bd03..8c0e75c0 100644 --- a/test/mons/PengymTest.sol +++ b/test/mons/PengymTest.sol @@ -180,7 +180,7 @@ contract PengymTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Check that Alice's mon has the PostWorkout effect @@ -216,12 +216,12 @@ contract PengymTest is Test, BattleHelper { // Alice switches to her second mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); // Alice switches back to her first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); // Check that Alice's mon no longer has the PanicStatus effect @@ -355,7 +355,7 @@ contract PengymTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Check that Alice's mon has the PostWorkout effect @@ -396,12 +396,12 @@ contract PengymTest is Test, BattleHelper { // Alice switches to her second mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); // Alice switches back to her first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); // Check that Alice's mon no longer has the FrostbiteStatus effect @@ -472,25 +472,25 @@ contract PengymTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice deals damage to Bob, record the damage dealt _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); int32 deepFreezeDamage = -1 * engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); // Alice inflicts frostbite on Bob, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); int32 bobDamageBefore = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); // Alice uses deep freeze, record the damage dealt _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); int32 bobDamageAfter = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); @@ -576,11 +576,11 @@ contract PengymTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice selects pistol squat, Bob selects move index 1 and outspeeds - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 1, uint240(0), uint240(0)); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, 1, uint16(0), uint16(0)); // Alice should be KO'ed int32 koFlag = engine.getMonStateForBattle(battleKey, 0, 0, MonStateIndexName.IsKnockedOut); @@ -588,11 +588,11 @@ contract PengymTest is Test, BattleHelper { // Alice swaps to mon index 1 vm.startPrank(ALICE); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice selects pistol squat, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Active mon for Bob should be 1 @@ -601,7 +601,7 @@ contract PengymTest is Test, BattleHelper { // Alice selects pistol squat, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Active mon for Bob should be 0 @@ -610,7 +610,7 @@ contract PengymTest is Test, BattleHelper { // Alice selects pistol squat, Bob does nothing (and dies) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); bobActiveMonIndex = engine.getActiveMonIndexForBattleState(battleKey)[1]; @@ -618,21 +618,21 @@ contract PengymTest is Test, BattleHelper { // Bob sends in mon index 1 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(1), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(1), true); engine.resetCallContext(); // Alice selects pistol squat, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Now Bob's mon index 1 is KOed // Bob sends in mon index 2 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint240(2), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, 0, uint16(2), true); engine.resetCallContext(); // Alice selects pistol squat, Bob does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Now Bob has mon index 2 (already took damage) and mon index 3 @@ -641,21 +641,21 @@ contract PengymTest is Test, BattleHelper { // Bob switches back to mon index 2, Alice does nothing _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(2) + engine, commitManager, battleKey, NO_OP_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(2) ); // Alice KOs Bob's mon index 2 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); // Bob sends in mon index 3 vm.startPrank(BOB); - commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, "", uint240(3), true); + commitManager.revealMove(battleKey, SWITCH_MOVE_INDEX, uint104(0), uint16(3), true); engine.resetCallContext(); // Alice tries to force a switch, but active mon should not change _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), uint16(0) ); bobActiveMonIndex = engine.getActiveMonIndexForBattleState(battleKey)[1]; assertEq(bobActiveMonIndex, 3, "No mons left"); diff --git a/test/mons/SofabbiTest.sol b/test/mons/SofabbiTest.sol index ab64d93d..0221faf7 100644 --- a/test/mons/SofabbiTest.sol +++ b/test/mons/SofabbiTest.sol @@ -108,7 +108,7 @@ contract SofabbiTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify that the CarrotHarvest effect was applied to Alice's mon @@ -117,12 +117,12 @@ contract SofabbiTest is Test, BattleHelper { // Now have Alice switch to her second mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0 ); // Now have Alice switch back to her first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0 + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0 ); // Verify that the CarrotHarvest effect is still only applied once @@ -188,7 +188,7 @@ contract SofabbiTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify that staminaDelta is 1 for both mons @@ -297,28 +297,28 @@ contract SofabbiTest is Test, BattleHelper { // First move: Both players select their first mon (index 0, the Air mon) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Damage is returned in negative, so that's why there are some weird sign cancellations below // Alice uses Guest Feature targeting mon index 1, it should deal 2x damage _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(1), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(1), uint16(0) ); int32 bobDmg = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); assertApproxEqRel(-1 * bobDmg, int32(2 * gf.BASE_POWER()), 2e17); // Alice uses Guest Feature targeting mon index 2, it should deal 0 damage _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(2), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(2), uint16(0) ); int32 newBobDmg = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); assertEq(newBobDmg, bobDmg, "No damage"); // Alice uses Guest Feature targeting mon index 3, it should deal 1/2 damage _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(3), uint240(0) + engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(3), uint16(0) ); newBobDmg = engine.getMonStateForBattle(battleKey, 1, 0, MonStateIndexName.Hp); bobDmg = bobDmg - newBobDmg; @@ -377,7 +377,7 @@ contract SofabbiTest is Test, BattleHelper { // Both players send in mon index 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses nothing, Bob uses move index 1, puts Alice at 1 HP @@ -454,7 +454,7 @@ contract SofabbiTest is Test, BattleHelper { // Both players send in mon index 0 _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Set rng to be 10 diff --git a/test/mons/VolthareTest.sol b/test/mons/VolthareTest.sol index 7991286b..3f222e21 100644 --- a/test/mons/VolthareTest.sol +++ b/test/mons/VolthareTest.sol @@ -124,7 +124,7 @@ contract VolthareTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Verify that Bob's mon took damage from PreemptiveShock @@ -207,11 +207,11 @@ contract VolthareTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses the Overclock move (move index 0), Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 0, NO_OP_MOVE_INDEX, uint16(0), 0); // Verify that Overclock is applied (EffectInstance[] memory effects,) = engine.getEffects(battleKey, 2, 0); @@ -222,7 +222,7 @@ contract VolthareTest is Test, BattleHelper { mockOracle.setRNG(2); // Alice uses Mega Star Blast (move index 1), Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), 0); // Verify that Bob's mon is zapped (effects,) = engine.getEffects(battleKey, 1, 0); @@ -237,7 +237,7 @@ contract VolthareTest is Test, BattleHelper { mockOracle.setRNG(msb.BASE_ACCURACY() + 1); // Alice uses Mega Star Blast, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), 0); // Verify that Bob's mon is not zapped (again) (effects,) = engine.getEffects(battleKey, 1, 0); @@ -303,7 +303,7 @@ contract VolthareTest is Test, BattleHelper { // Both players send in their mons _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Bob applies Overclock (stored with player index 1). Alice does nothing. @@ -320,7 +320,7 @@ contract VolthareTest is Test, BattleHelper { mockOracle.setRNG(msb.BASE_ACCURACY() + 1); // Alice uses MegaStarBlast. Bob does nothing. - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, uint16(0), 0); // Overclock should still be present (Alice cannot clear Bob's Overclock) (effects,) = engine.getEffects(battleKey, 2, 0); @@ -396,7 +396,7 @@ contract VolthareTest is Test, BattleHelper { // First move: Both players select their first mon (index 0) _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Both players use Dual Shock, Alice should move first and skip their next move diff --git a/test/mons/XmonTest.sol b/test/mons/XmonTest.sol index 10b041b6..8c3d995d 100644 --- a/test/mons/XmonTest.sol +++ b/test/mons/XmonTest.sol @@ -87,7 +87,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Contagious Slumber, Bob does nothing @@ -160,7 +160,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Set RNG to guarantee stamina steal (>= 50) @@ -219,7 +219,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Alice uses Somniphobia, Bob uses Somniphobia too @@ -337,7 +337,7 @@ contract XmonTest is Test, BattleHelper { // Alice sends in fast mon, Bob sends in slow mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(1) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(1) ); // Verify that Alice has the Dreamcatcher effect @@ -400,7 +400,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Turn 1: Alice uses Night Terrors, Bob does nothing @@ -467,7 +467,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Turn 1: Alice uses Night Terrors, Bob does nothing @@ -485,7 +485,7 @@ contract XmonTest is Test, BattleHelper { assertTrue(hasNightTerrorsBeforeSwap, "Alice's mon 0 should have Night Terrors effect before swap"); // Turn 2: Alice swaps to mon 1, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0); // Verify Alice's mon 0 no longer has Night Terrors effect (EffectInstance[] memory aliceEffectsAfterSwap, ) = engine.getEffects(battleKey, 0, 0); @@ -555,7 +555,7 @@ contract XmonTest is Test, BattleHelper { // Both players select their first mon _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Set RNG to 1 to prevent early waking from sleep (rng % 3 == 0 wakes early) @@ -569,10 +569,10 @@ contract XmonTest is Test, BattleHelper { int32 awakeDamage = -bobHpAfterAwakeDamage; // Turn 2: Alice swaps out to mon 1 to clear Night Terrors, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(1), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(1), 0); // Turn 3: Alice swaps back to mon 0, Bob does nothing - _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint240(0), 0); + _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, SWITCH_MOVE_INDEX, NO_OP_MOVE_INDEX, uint16(0), 0); // Turn 4: Alice uses Sleep move on Bob, Bob does nothing _commitRevealExecuteForAliceAndBob(engine, commitManager, battleKey, 1, NO_OP_MOVE_INDEX, 0, 0); diff --git a/test/moves/StandardAttackRngTest.sol b/test/moves/StandardAttackRngTest.sol index d06be33b..836976cc 100644 --- a/test/moves/StandardAttackRngTest.sol +++ b/test/moves/StandardAttackRngTest.sol @@ -93,7 +93,7 @@ contract StandardAttackRngTest is Test, BattleHelper { // Switch in mon 0 on both sides. _commitRevealExecuteForAliceAndBob( - engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint240(0), uint240(0) + engine, commitManager, battleKey, SWITCH_MOVE_INDEX, SWITCH_MOVE_INDEX, uint16(0), uint16(0) ); // Oracle returns the same rng for both attackers this turn.