Compare commits
2 Commits
fe9f92281b
...
28cf9d6de8
| Author | SHA1 | Date | |
|---|---|---|---|
| 28cf9d6de8 | |||
| 4327971456 |
@ -10,6 +10,7 @@ import {StorageHistory} from "./types/StorageHistory.sol";
|
|||||||
import {Weaver} from "./types/Weaver.sol";
|
import {Weaver} from "./types/Weaver.sol";
|
||||||
|
|
||||||
import {FullMath} from "./libraries/FullMath.sol";
|
import {FullMath} from "./libraries/FullMath.sol";
|
||||||
|
import {Verifier} from "./libraries/Verifier.sol";
|
||||||
import {Checkpoints} from "./libraries/Checkpoints.sol";
|
import {Checkpoints} from "./libraries/Checkpoints.sol";
|
||||||
import {RotationPacking, RequestPacking, GovernancePacking} from "./libraries/Packing.sol";
|
import {RotationPacking, RequestPacking, GovernancePacking} from "./libraries/Packing.sol";
|
||||||
import {ReentrancyGuard} from "@openzeppelin-contracts/utils/ReentrancyGuard.sol";
|
import {ReentrancyGuard} from "@openzeppelin-contracts/utils/ReentrancyGuard.sol";
|
||||||
@ -22,7 +23,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
|
|
||||||
uint256 private constant BOUNTY_DIVISOR = type(uint32).max;
|
uint256 private constant BOUNTY_DIVISOR = type(uint32).max;
|
||||||
uint256 private constant SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
|
uint256 private constant SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
|
||||||
uint256 private constant SECP256K1_Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
|
uint256 private constant SECP256K1_Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
|
||||||
uint256 private constant SHIFT_FACTOR = (2**128) % SECP256K1_N;
|
uint256 private constant SHIFT_FACTOR = (2**128) % SECP256K1_N;
|
||||||
|
|
||||||
uint256 public constant GAS_RECALL_SPENDING = 329188;
|
uint256 public constant GAS_RECALL_SPENDING = 329188;
|
||||||
@ -113,12 +114,14 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
|
|
||||||
function verify(
|
function verify(
|
||||||
bytes calldata call,
|
bytes calldata call,
|
||||||
bytes calldata nonce,
|
uint256 rx,
|
||||||
bytes32 s
|
uint256 s
|
||||||
) external nonReentrant payable returns (bytes memory) {
|
) external nonReentrant returns (bytes memory) {
|
||||||
_verifySchnorrSignature(call, nonce, s);
|
uint256 px = _extractPublicKey(call);
|
||||||
|
bool validSignature = Verifier.verifyGhost(call, px, rx, s);
|
||||||
|
if (!validSignature) revert BadSignature();
|
||||||
|
|
||||||
(bool success, bytes memory data) = address(this).call{ value: msg.value }(call);
|
(bool success, bytes memory data) = address(this).call(call);
|
||||||
if (!success) revert ExecutionReverted();
|
if (!success) revert ExecutionReverted();
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -138,7 +141,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
uint256 exodusSession,
|
uint256 exodusSession,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 packed
|
uint256 packed
|
||||||
) external override payable {
|
) external override {
|
||||||
if (msg.sender != address(this)) revert NotGatekeeper();
|
if (msg.sender != address(this)) revert NotGatekeeper();
|
||||||
|
|
||||||
RequestPacking.RequestPayload memory payload = RequestPacking.unpack(packed);
|
RequestPacking.RequestPayload memory payload = RequestPacking.unpack(packed);
|
||||||
@ -173,8 +176,9 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
uint8 newParity
|
uint8 newParity
|
||||||
) external override {
|
) external override {
|
||||||
if (msg.sender != address(this)) revert NotGatekeeper();
|
if (msg.sender != address(this)) revert NotGatekeeper();
|
||||||
StorageHistory(storageHistory).trySetTransactionExecuted(exodusSession);
|
if (newParity % 2 != 0) revert InvalidPublicKey();
|
||||||
|
|
||||||
|
StorageHistory(storageHistory).trySetTransactionExecuted(exodusSession);
|
||||||
// forge-lint: disable-next-line(unsafe-typecast)
|
// forge-lint: disable-next-line(unsafe-typecast)
|
||||||
uint256 packedRotationState = RotationPacking.pack(newParity, uint64(exodusSession));
|
uint256 packedRotationState = RotationPacking.pack(newParity, uint64(exodusSession));
|
||||||
|
|
||||||
@ -202,85 +206,15 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _verifySchnorrSignature(bytes calldata call, bytes calldata nonce, bytes32 s) internal view {
|
function _extractPublicKey(bytes calldata call) internal view returns (uint256) {
|
||||||
(bytes32 px, uint8 p) = _extractPublicKey(call);
|
|
||||||
|
|
||||||
uint8 v = p == 0 ? 27 : 28;
|
|
||||||
bytes32 e = _challenge(call, nonce, px, p);
|
|
||||||
|
|
||||||
bytes32 sp = bytes32(SECP256K1_Q - mulmod(uint256(s), uint256(px), SECP256K1_Q));
|
|
||||||
bytes32 ep = bytes32(SECP256K1_Q - mulmod(uint256(e), uint256(px), SECP256K1_Q));
|
|
||||||
address recoveredR = ecrecover(sp, v, px, ep);
|
|
||||||
|
|
||||||
if (sp == 0) revert BadSignature();
|
|
||||||
if (recoveredR == address(0)) revert BadSignature();
|
|
||||||
if (recoveredR != _uncompressedPointToAddress(nonce)) revert BadSignature();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _uncompressedPointToAddress(bytes calldata nonce) internal pure returns (address) {
|
|
||||||
if (nonce.length != 65) revert BadSignature();
|
|
||||||
if (nonce[0] != 0x04) revert BadSignature();
|
|
||||||
|
|
||||||
bytes32 rx = bytes32(nonce[1:33]);
|
|
||||||
bytes32 ry = bytes32(nonce[33:65]);
|
|
||||||
|
|
||||||
return address(uint160(uint256(keccak256(abi.encodePacked(rx, ry)))));
|
|
||||||
}
|
|
||||||
|
|
||||||
function _extractPublicKey(bytes calldata call) internal view returns (bytes32, uint8) {
|
|
||||||
if (call.length < 36) revert InvalidCalldata();
|
if (call.length < 36) revert InvalidCalldata();
|
||||||
uint256 exodusSession;
|
uint256 exodusSession;
|
||||||
assembly {
|
assembly {
|
||||||
exodusSession := calldataload(add(call.offset, 4))
|
exodusSession := calldataload(add(call.offset, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
(bytes32 publicKey, uint8 parity,) = getRotationInfoAt(exodusSession);
|
(bytes32 publicKey,,) = getRotationInfoAt(exodusSession);
|
||||||
|
|
||||||
return (publicKey, parity);
|
return uint256(publicKey);
|
||||||
}
|
|
||||||
|
|
||||||
function _challenge(
|
|
||||||
bytes calldata call,
|
|
||||||
bytes calldata r,
|
|
||||||
bytes32 pk,
|
|
||||||
uint8 v
|
|
||||||
) internal pure returns (bytes32) {
|
|
||||||
if (r.length != 65) revert BadSignature();
|
|
||||||
|
|
||||||
bytes32 rx = bytes32(r[1:33]);
|
|
||||||
bytes1 rv;
|
|
||||||
|
|
||||||
{
|
|
||||||
bytes32 ry = bytes32(r[33:65]);
|
|
||||||
uint8 rParityByte = (uint256(ry) & 1) == 0 ? 0x02 : 0x03;
|
|
||||||
rv = bytes1(rParityByte);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 pv = v == 0 ? 0x02 : 0x03;
|
|
||||||
|
|
||||||
bytes memory message = abi.encodePacked(rv, rx, pv, pk, call);
|
|
||||||
bytes memory domain = "FROST-secp256k1-SHA256-v1chal";
|
|
||||||
uint8 dstlen = uint8(domain.length);
|
|
||||||
|
|
||||||
bytes32 b0 = sha256(abi.encodePacked(
|
|
||||||
bytes32(0),
|
|
||||||
bytes32(0),
|
|
||||||
message,
|
|
||||||
hex"0030",
|
|
||||||
uint8(0),
|
|
||||||
domain,
|
|
||||||
dstlen
|
|
||||||
));
|
|
||||||
|
|
||||||
bytes32 b1 = sha256(abi.encodePacked(b0, uint8(1), domain, dstlen));
|
|
||||||
bytes32 b2 = sha256(abi.encodePacked(b0 ^ b1, uint8(2), domain, dstlen));
|
|
||||||
|
|
||||||
uint256 high32 = uint256(b1);
|
|
||||||
uint256 lowPart = uint256(b2) >> 128;
|
|
||||||
|
|
||||||
uint256 highReduced = mulmod(high32, SHIFT_FACTOR, SECP256K1_N);
|
|
||||||
uint256 finalChallenge = addmod(highReduced, lowPart, SECP256K1_N);
|
|
||||||
|
|
||||||
return bytes32(finalChallenge);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ interface IGatekeeper {
|
|||||||
error NotGatekeeper();
|
error NotGatekeeper();
|
||||||
error AlreadyExecuted();
|
error AlreadyExecuted();
|
||||||
error InvalidCalldata();
|
error InvalidCalldata();
|
||||||
|
error InvalidPublicKey();
|
||||||
error NonExistentAmount();
|
error NonExistentAmount();
|
||||||
error InsufficientValue();
|
error InsufficientValue();
|
||||||
error ExecutionReverted();
|
error ExecutionReverted();
|
||||||
@ -25,7 +26,7 @@ interface IGatekeeper {
|
|||||||
function getRotationInfoAt(uint256 session) external view returns (bytes32, uint8, uint64);
|
function getRotationInfoAt(uint256 session) external view returns (bytes32, uint8, uint64);
|
||||||
|
|
||||||
function govern(uint256 session, uint256 payload, bytes calldata call) external returns (bytes calldata);
|
function govern(uint256 session, uint256 payload, bytes calldata call) external returns (bytes calldata);
|
||||||
function recall(uint256 session, uint256 amount, uint256 payload) external payable;
|
function recall(uint256 session, uint256 amount, uint256 payload) external;
|
||||||
function rotate(uint256 session, bytes32 publicKey, uint8 parity) external;
|
function rotate(uint256 session, bytes32 publicKey, uint8 parity) external;
|
||||||
function ghost(bytes32 receiver, uint256 amount) external returns (uint256);
|
function ghost(bytes32 receiver, uint256 amount) external returns (uint256);
|
||||||
function initialize(address previousAddress) external;
|
function initialize(address previousAddress) external;
|
||||||
|
|||||||
@ -17,12 +17,30 @@ library Hashes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function efficientKeccak256(bytes32 a, bytes32 b, bytes32 c) internal pure returns (bytes32 value) {
|
function efficientKeccak256(uint256 a, uint256 b) internal pure returns (bytes32 value) {
|
||||||
assembly ("memory-safe") {
|
assembly ("memory-safe") {
|
||||||
mstore(0x00, a)
|
mstore(0x00, a)
|
||||||
mstore(0x20, b)
|
mstore(0x20, b)
|
||||||
mstore(0x40, c)
|
value := keccak256(0x00, 0x40)
|
||||||
value := keccak256(0x00, 0x60)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function efficientKeccak256Prefixed(bytes32 a) internal pure returns (bytes32 value) {
|
||||||
|
assembly ("memory-safe") {
|
||||||
|
let ptr := mload(0x40)
|
||||||
|
mstore8(ptr, 0x00)
|
||||||
|
mstore(add(ptr, 0x01), a)
|
||||||
|
value := keccak256(ptr, 0x21)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function efficientKeccak256Prefixed(bytes32 a, bytes32 b) internal pure returns (bytes32 value) {
|
||||||
|
assembly ("memory-safe") {
|
||||||
|
let ptr := mload(0x40)
|
||||||
|
mstore8(ptr, 0x01)
|
||||||
|
mstore(add(ptr, 0x01), a)
|
||||||
|
mstore(add(ptr, 0x21), b)
|
||||||
|
value := keccak256(ptr, 0x41)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
380
src/libraries/Verifier.sol
Normal file
380
src/libraries/Verifier.sol
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.20;
|
||||||
|
|
||||||
|
import {Hashes} from "./Hashes.sol";
|
||||||
|
|
||||||
|
// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
||||||
|
|
||||||
|
library Verifier {
|
||||||
|
// Constants: https://en.bitcoin.it/wiki/Secp256k1
|
||||||
|
uint256 internal constant N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
|
||||||
|
uint256 internal constant P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
|
||||||
|
uint256 internal constant GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;
|
||||||
|
uint256 internal constant GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;
|
||||||
|
uint256 internal constant EXP = 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFF0C;
|
||||||
|
uint256 internal constant B = 7;
|
||||||
|
|
||||||
|
function verifyGhost(
|
||||||
|
bytes memory call,
|
||||||
|
uint256 px,
|
||||||
|
uint256 rx,
|
||||||
|
uint256 s
|
||||||
|
) internal view returns (bool) {
|
||||||
|
if (px >= P || rx >= P || s >= N || s == 0) { return false; }
|
||||||
|
if (rx < N) { return verifySpectre(call, px, rx, s); }
|
||||||
|
|
||||||
|
(uint256 py, bool success1) = liftPoint(px);
|
||||||
|
(uint256 ry, bool success2) = liftPoint(rx);
|
||||||
|
if (!success1 || !success2) { return false; }
|
||||||
|
|
||||||
|
return verifyBanshee(call, px, py, rx, ry, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifySpectre(
|
||||||
|
bytes memory call,
|
||||||
|
uint256 px,
|
||||||
|
uint256 rx,
|
||||||
|
uint256 s
|
||||||
|
) internal view returns (bool) {
|
||||||
|
uint256 e = computeChallenge(call, rx, px);
|
||||||
|
(address convertedR, bool success) = point2Address(rx);
|
||||||
|
if (!success) { return false; }
|
||||||
|
|
||||||
|
// Explanation: https://hackmd.io/@nZ-twauPRISEa6G9zg3XRw/SyjJzSLt9
|
||||||
|
bytes32 sp = bytes32(N - mulmod(s, px, N));
|
||||||
|
bytes32 ep = bytes32(N - mulmod(e, px, N));
|
||||||
|
|
||||||
|
// Parity should be always even
|
||||||
|
address recoveredR = ecrecover(sp, 27, bytes32(px), ep);
|
||||||
|
return recoveredR == convertedR;
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyBanshee(
|
||||||
|
bytes memory call,
|
||||||
|
uint256 px,
|
||||||
|
uint256 py,
|
||||||
|
uint256 rx,
|
||||||
|
uint256 ry,
|
||||||
|
uint256 s
|
||||||
|
) internal pure returns (bool) {
|
||||||
|
// TODO: because I lift it before, do I need to check is it on curve?
|
||||||
|
// both of them Px,Py and Rx,Ry
|
||||||
|
if (!isOnCurve(rx, ry) || !isOnCurve(px, py)) { return false; }
|
||||||
|
|
||||||
|
uint256 e = computeChallenge(call, rx, px);
|
||||||
|
if (e == 0) return false; // Cheap and safe
|
||||||
|
|
||||||
|
// s ⋅ G = R + hash(R || m) ⋅ Y
|
||||||
|
// R = s ⋅ G + hash(R || m) ⋅ Y
|
||||||
|
(uint256 x, uint256 y, uint256 z) = multiScalarMulAdd(GX, GY, s, px, py, N - e);
|
||||||
|
(x, y) = toAffine(x, y, z);
|
||||||
|
|
||||||
|
if (!isOnCurve(x, y)) return false;
|
||||||
|
return x == rx && y == ry;
|
||||||
|
}
|
||||||
|
|
||||||
|
function point2Address(uint256 rx) internal view returns (address, bool) {
|
||||||
|
(uint256 ry, bool success) = liftPoint(rx);
|
||||||
|
if (!success) { return (address(0), false); }
|
||||||
|
|
||||||
|
bytes32 encodedR = Hashes.efficientKeccak256(rx, ry);
|
||||||
|
address addressR = address(uint160(uint256(encodedR)));
|
||||||
|
return (addressR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function liftPoint(uint256 x) internal view returns (uint256, bool) {
|
||||||
|
if (x >= P) { return (0, false); }
|
||||||
|
|
||||||
|
// y^2 = x^3 + 7 (mod P)
|
||||||
|
uint256 y2 = addmod(mulmod(x, mulmod(x, x, P), P), B, P);
|
||||||
|
y2 = expModPrecompile(y2);
|
||||||
|
|
||||||
|
uint256 y = (y2 & 1) == 0 ? y2 : P - y2; // BIP-340: point is always even
|
||||||
|
if (!isOnCurve(x, y)) { return (0, false); } // point does not exist on curve
|
||||||
|
|
||||||
|
return (y, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expModPrecompile(uint256 base) internal view returns (uint256 result) {
|
||||||
|
uint256 localEXP = EXP;
|
||||||
|
uint256 localP = P;
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
let pointer := mload(0x40)
|
||||||
|
|
||||||
|
mstore(pointer, 0x20)
|
||||||
|
mstore(add(pointer, 0x20), 0x20)
|
||||||
|
mstore(add(pointer, 0x40), 0x20)
|
||||||
|
|
||||||
|
mstore(add(pointer, 0x60), base)
|
||||||
|
mstore(add(pointer, 0x80), localEXP)
|
||||||
|
mstore(add(pointer, 0xa0), localP)
|
||||||
|
|
||||||
|
// Modular Exponentiation Precompile (modexp)
|
||||||
|
let success := staticcall(gas(), 0x05, pointer, 0xc0, pointer, 0x20)
|
||||||
|
if iszero(success) { revert(0, 0) }
|
||||||
|
|
||||||
|
result := mload(pointer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeChallenge(bytes memory call, uint256 rx, uint256 px) internal pure returns (uint256) {
|
||||||
|
// Precomputed `sha256("BIP0340/challenge")`
|
||||||
|
bytes32 tag = 0x7bb52d7a9fef58323eb1bf7a407db382d2f3f2d81bb1224f49fe518f6d48d37c;
|
||||||
|
return uint256(sha256(abi.encodePacked(tag, tag, rx, px, call))) % N;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findMaxBitLength(uint256 k1, uint256 k2) internal pure returns (uint256 bits) {
|
||||||
|
assembly {
|
||||||
|
// Find maximum of the three scalars
|
||||||
|
let max := k1
|
||||||
|
if gt(k2, max) { max := k2 }
|
||||||
|
|
||||||
|
// if (v >> 128 != 0) { v >>= 128; bits += 128; }
|
||||||
|
if gt(max, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {
|
||||||
|
max := shr(128, max)
|
||||||
|
bits := 128
|
||||||
|
}
|
||||||
|
// if (v >> 64 != 0) { v >>= 64; bits += 64; }
|
||||||
|
if gt(max, 0xFFFFFFFFFFFFFFFF) {
|
||||||
|
max := shr(64, max)
|
||||||
|
bits := add(bits, 64)
|
||||||
|
}
|
||||||
|
// if (v >> 32 != 0) { v >>= 32; bits += 32; }
|
||||||
|
if gt(max, 0xFFFFFFFF) {
|
||||||
|
max := shr(32, max)
|
||||||
|
bits := add(bits, 32)
|
||||||
|
}
|
||||||
|
// if (v >> 16 != 0) { v >>= 16; bits += 16; }
|
||||||
|
if gt(max, 0xFFFF) {
|
||||||
|
max := shr(16, max)
|
||||||
|
bits := add(bits, 16)
|
||||||
|
}
|
||||||
|
// if (v >> 8 != 0) { v >>= 8; bits += 8; }
|
||||||
|
if gt(max, 0xFF) {
|
||||||
|
max := shr(8, max)
|
||||||
|
bits := add(bits, 8)
|
||||||
|
}
|
||||||
|
// if (v >> 4 != 0) { v >>= 4; bits += 4; }
|
||||||
|
if gt(max, 0xF) {
|
||||||
|
max := shr(4, max)
|
||||||
|
bits := add(bits, 4)
|
||||||
|
}
|
||||||
|
// if (v >> 2 != 0) { v >>= 2; bits += 2; }
|
||||||
|
if gt(max, 0x3) {
|
||||||
|
max := shr(2, max)
|
||||||
|
bits := add(bits, 2)
|
||||||
|
}
|
||||||
|
// if (v >> 1 != 0) { /* v >>= 1; */ bits += 1; }
|
||||||
|
if gt(max, 0x1) {
|
||||||
|
bits := add(bits, 1)
|
||||||
|
}
|
||||||
|
bits := add(bits, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toAffine(uint256 x, uint256 y, uint256 z) internal pure returns (uint256, uint256) {
|
||||||
|
if (z == 0) return (0, 0); // Identity point
|
||||||
|
uint256 t0;
|
||||||
|
assembly {
|
||||||
|
// Extended Euclidean algorithm (iterative, assembly)
|
||||||
|
// Typically lower average gas than the modexp precompile for single inversions,
|
||||||
|
// but execution time (and gas) depends on input values — not constant-time.
|
||||||
|
|
||||||
|
let t1 := 1
|
||||||
|
let r0 := P
|
||||||
|
let r1 := z
|
||||||
|
|
||||||
|
for {} r1 {} {
|
||||||
|
let q := div(r0, r1)
|
||||||
|
|
||||||
|
// t0, t1 = t1, t0 - q * t1
|
||||||
|
let t1_new := sub(t0, mul(q, t1))
|
||||||
|
t0 := t1
|
||||||
|
t1 := t1_new
|
||||||
|
|
||||||
|
// r0, r1 = r1, r0 - q * r1
|
||||||
|
let r1_new := sub(r0, mul(q, r1))
|
||||||
|
r0 := r1
|
||||||
|
r1 := r1_new
|
||||||
|
}
|
||||||
|
|
||||||
|
if slt(t0, 0) {
|
||||||
|
t0 := add(t0, P)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (mulmod(x, t0, P), mulmod(y, t0, P));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOnCurve(uint256 x, uint256 y) internal pure returns (bool) {
|
||||||
|
if (x >= P || y >= P) return false;
|
||||||
|
if (x == 0 && y == 0) return false; // Identity point
|
||||||
|
|
||||||
|
uint lhs = mulmod(y, y, P); // y^2
|
||||||
|
uint rhs = mulmod(mulmod(x, x, P), x, P); // x^3
|
||||||
|
rhs = addmod(rhs, B, P); // x^3 + 7
|
||||||
|
|
||||||
|
return lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function multiScalarMulAdd(
|
||||||
|
uint256 x1, uint256 y1, uint256 k1,
|
||||||
|
uint256 x2, uint256 y2, uint256 k2
|
||||||
|
) internal pure returns (uint256 x3, uint256 y3, uint256 z3) {
|
||||||
|
// Implementation of the Straus-Shamir trick described in
|
||||||
|
// Trading Inversions for Multiplications in Elliptic Curve Cryptography.
|
||||||
|
// (https://eprint.iacr.org/2003/257.pdf Page 7).
|
||||||
|
|
||||||
|
uint256 bits = findMaxBitLength(k1, k2);
|
||||||
|
|
||||||
|
uint256[4] memory precomputedXs;
|
||||||
|
uint256[4] memory precomputedYs;
|
||||||
|
uint256[4] memory precomputedZs;
|
||||||
|
|
||||||
|
precomputedXs[1] = x2; precomputedYs[1] = y2; precomputedZs[1] = 1; // 01: P2
|
||||||
|
precomputedXs[2] = x1; precomputedYs[2] = y1; precomputedZs[2] = 1; // 10: P1
|
||||||
|
(precomputedXs[3], precomputedYs[3], precomputedZs[3]) = projectiveAdd(x1, y1, 1, x2, y2, 1); // 11: P1+P2
|
||||||
|
|
||||||
|
y3 = 1;
|
||||||
|
|
||||||
|
for (; bits > 0;) {
|
||||||
|
unchecked { --bits; }
|
||||||
|
(x3, y3, z3) = projectiveDouble(x3, y3, z3);
|
||||||
|
|
||||||
|
uint8 mask;
|
||||||
|
assembly {
|
||||||
|
mask := or(
|
||||||
|
shl(1, and(shr(bits, k1), 1)),
|
||||||
|
and(shr(bits, k2), 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask == 0) { continue; }
|
||||||
|
|
||||||
|
if (mask == 3) {
|
||||||
|
(x3, y3, z3) = projectiveAdd(
|
||||||
|
x3, y3, z3, precomputedXs[mask], precomputedYs[mask], precomputedZs[mask]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
(x3, y3, z3) = projectiveAddMixed(
|
||||||
|
x3, y3, z3, precomputedXs[mask], precomputedYs[mask]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function projectiveDouble(
|
||||||
|
uint256 x,
|
||||||
|
uint256 y,
|
||||||
|
uint256 z
|
||||||
|
) internal pure returns (uint256 x3, uint256 y3, uint256 z3) {
|
||||||
|
// Implementation of the complete addition formula from Renes-Costello-Batina 2015
|
||||||
|
// (https://eprint.iacr.org/2015/1060 Algorithm 9).
|
||||||
|
|
||||||
|
// X3 = 2XY (Y^2 − 9bZ^2), (ok)
|
||||||
|
// Y3 = (Y^2 − 9bZ^2)(Y^2 + 3bZ^2) + 24bY^2Z^2,
|
||||||
|
// Z3 = 8Y^3Z
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
let t0 := mulmod(y, y, P) // t0 = y²
|
||||||
|
z3 := mulmod(8, t0, P) // z3 = 8y²
|
||||||
|
let t1 := mulmod(y, z, P) // t1 = y·z
|
||||||
|
let t2 := mulmod(z, z, P) // t2 = z²
|
||||||
|
t2 := mulmod(21, t2, P) // t2 = 3b·z² (b=7 → 3b=21)
|
||||||
|
x3 := mulmod(t2, z3, P) // x3 = (3b·z²)(8y²) = 24b·y²·z²
|
||||||
|
y3 := addmod(t0, t2, P) // y3 = y² + 3b·z²
|
||||||
|
z3 := mulmod(t1, z3, P) // z3 = (y·z)(8y²) = 8y³·z
|
||||||
|
t1 := addmod(t0, sub(P, mulmod(3, t2, P)), P) // t1 = y² − 9b·z²
|
||||||
|
y3 := addmod(x3, mulmod(t1, y3, P), P) // y3 = 24b·y²·z² + (y²−9b·z²)(y²+3b·z²)
|
||||||
|
x3 := mulmod(t1, mulmod(x, y, P), P) // x3 = (y²−9b·z²)·x·y
|
||||||
|
x3 := addmod(x3, x3, P) // x3 = 2xy·(y²−9b·z²)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function projectiveAdd(
|
||||||
|
uint256 x1, uint256 y1, uint256 z1,
|
||||||
|
uint256 x2, uint256 y2,uint256 z2
|
||||||
|
) internal pure returns (uint256 x3, uint256 y3, uint256 z3) {
|
||||||
|
// Implementation of the complete addition formula from Renes-Costello-Batina 2015
|
||||||
|
// (https://eprint.iacr.org/2015/1060 Algorithm 7).
|
||||||
|
|
||||||
|
// X3 = (X1Y2 + X2Y1)(Y1Y2 − 3bZ1Z2) − 3b(Y1Z2 + Y2Z1)(X1Z2 + X2Z1),
|
||||||
|
// Y3 = (Y1Y2 + 3bZ1Z2)(Y1Y2 − 3bZ1Z2) + 9bX1X2(X1Z2 + X2Z1),
|
||||||
|
// Z3 = (Y1Z2 + Y2Z1)(Y1Y2 + 3bZ1Z2) + 3X1X2(X1Y2 + X2Y1),
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
let t0 := mulmod(x1, x2, P) // 1. t0 ← X1 · X2 => (X1·X2)
|
||||||
|
let t1 := mulmod(y1, y2, P) // 2. t1 ← Y1 · Y2 => (Y1·Y2)
|
||||||
|
let t2 := mulmod(z1, z2, P) // 3. t2 ← Z1 · Z2 => (Z1·Z2)
|
||||||
|
let t3 := addmod(x1, y1, P) // 4. t3 ← X1 + Y1 => (X1 + Y1)
|
||||||
|
let t4 := addmod(x2, y2, P) // 5. t4 ← X2 + Y2 => (X2 + Y2)
|
||||||
|
t3 := mulmod(t3, t4, P) // 6. t3 ← t3 · t4 => ((X1 + Y1) · (X2 + Y2))
|
||||||
|
t4 := addmod(t0, t1, P) // 7. t4 ← t0 + t1 => (X1·X2 + Y1·Y2)
|
||||||
|
t3 := addmod(t3, sub(P, t4), P) // 8. t3 ← t3 - t4 => ((X1 + Y1)·(X2 + Y2) - X1·X2 - Y1·Y2)
|
||||||
|
t4 := addmod(y1, z1, P) // 9. t4 ← Y1 + Z1 => (Y1 + Z1)
|
||||||
|
x3 := addmod(y2, z2, P) // 10. X3 ← Y2 + Z2 => (Y2 + Z2)
|
||||||
|
t4 := mulmod(t4, x3, P) // 11. t4 ← t4 · X3 => ((Y1 + Z1) · (Y2 + Z2))
|
||||||
|
x3 := addmod(t1, t2, P) // 12. X3 ← t1 + t2 => (Y1·Y2 + Z1·Z2)
|
||||||
|
t4 := addmod(t4, sub(P, x3), P) // 13. t4 ← t4 - X3 => ((Y1 + Z1)·(Y2 + Z2) - Y1·Y2 - Z1·Z2)
|
||||||
|
x3 := addmod(x1, z1, P) // 14. X3 ← X1 + Z1 => (X1 + Z1)
|
||||||
|
y3 := addmod(x2, z2, P) // 15. Y3 ← X2 + Z2 => (X2 + Z2)
|
||||||
|
x3 := mulmod(x3, y3, P) // 16. X3 ← X3 · Y3 => ((X1 + Z1) · (X2 + Z2))
|
||||||
|
y3 := addmod(t0, t2, P) // 17. Y3 ← t0 + t2 => (X1·X2 + Z1·Z2)
|
||||||
|
y3 := addmod(x3, sub(P, y3), P) // 18. Y3 ← X3 - Y3 => ((X1 + Z1)·(X2 + Z2) - X1·X2 - Z1·Z2)
|
||||||
|
x3 := addmod(t0, t0, P) // 19. X3 ← t0 + t0 => (2·X1·X2)
|
||||||
|
t0 := addmod(x3, t0, P) // 20. t0 ← X3 + t0 => (3·X1·X2)
|
||||||
|
t2 := mulmod(21, t2, P) // 21. t2 ← B3 · t2 => 3b · Z1·Z2
|
||||||
|
z3 := addmod(t1, t2, P) // 22. Z3 ← t1 + t2 => Y1·Y2 + 3·b·Z1·Z2
|
||||||
|
t1 := addmod(t1, sub(P, t2), P) // 23. t1 ← t1 - t2 => Y1·Y2 - 3·b·Z1·Z2
|
||||||
|
y3 := mulmod(21, y3, P) // 24. Y3 ← B3 · Y3 => 3b · ((X1+Z1)(X2+Z2) - X1·X2 - Z1·Z2)
|
||||||
|
x3 := mulmod(t4, y3, P) // 25. X3 ← t4 · Y3 => 3b·((Y1+Z1)(Y2+Z2)-Y1·Y2-Z1·Z2) · ((X1+Z1)(X2+Z2)-X1·X2-Z1·Z2)
|
||||||
|
t2 := mulmod(t3, t1, P) // 26. t2 ← t3 · t1 => ((X1+Y1)(X2+Y2)-X1·X2-Y1·Y2) · (Y1·Y2 - 3·b·Z1·Z2)
|
||||||
|
x3 := addmod(t2, sub(P, x3), P) // 27. X3 ← t2 - X3 => (X1Y2+X2Y1)(Y1·Y2-3·b·Z1·Z2) - 3b(Y1·Z2+Y2·Z1)(X1·Z2+X2·Z1)
|
||||||
|
y3 := mulmod(y3, t0, P) // 28. Y3 ← Y3 · t0 => 3·b·((X1+Z1)(X2+Z2) - X1·X2 - Z1·Z2) · 3·X1·X2 = 9·b·X1·X2·(X1·Z2+X2·Z1)
|
||||||
|
t1 := mulmod(t1, z3, P) // 29. t1 ← t1 · Z3 => (Y1·Y2-3·b·Z1·Z2) · (Y1·Y2+3·b·Z1·Z2)
|
||||||
|
y3 := addmod(t1, y3, P) // 30. Y3 ← t1 + Y3 => (Y1Y2+3·b·Z1·Z2)(Y1·Y2-3·b·Z1·Z2) + 9b·X1·X2·(X1·Z2+X2·Z1)
|
||||||
|
t0 := mulmod(t0, t3, P) // 31. t0 ← t0 · t3 => (3·X1·X2) · ((X1+Y1)(X2+Y2)-X1·X2-Y1·Y2)
|
||||||
|
z3 := mulmod(z3, t4, P) // 32. Z3 ← Z3 · t4 => (Y1·Y2+3·b·Z1·Z2) · ((Y1+Z1)(Y2+Z2)-Y1·Y2-Z1·Z2)
|
||||||
|
z3 := addmod(z3, t0, P) // 33. Z3 ← Z3 + t0 => (Y1·Z2+Y2·Z1)·(Y1·Y2+3·b·Z1·Z2) + 3·X1·X2·(X1·Y2+X2·Y1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function projectiveAddMixed(
|
||||||
|
uint256 x1, uint256 y1, uint256 z1,
|
||||||
|
uint256 x2, uint256 y2
|
||||||
|
) internal pure returns (uint256 x3, uint256 y3, uint256 z3) {
|
||||||
|
// Implementation of the complete addition formula from Renes-Costello-Batina 2015
|
||||||
|
// (https://eprint.iacr.org/2015/1060 Algorithm 8).
|
||||||
|
|
||||||
|
// X3 = (X1Y2 + X2Y1)(Y1Y2 − 3bZ1) − 3b(Y1 + Y2Z1)(X1 + X2Z1),
|
||||||
|
// Y3 = (Y1Y2 + 3bZ1)(Y1Y2 − 3bZ1) + 9bX1X2(X1 + X2Z1),
|
||||||
|
// Z3 = (Y1 + Y2Z1)(Y1Y2 + 3bZ1) + 3X1X2(X1Y2 + X2Y1),
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
let t0 := mulmod(x1, x2, P) // 1. t0 ← X1 · X2 => (X1·X2)
|
||||||
|
let t1 := mulmod(y1, y2, P) // 2. t1 ← Y1 · Y2 => (Y1·Y2)
|
||||||
|
let t3 := mulmod(x2, y1, P) // 3. t3 ← X2 + Y2 => (X2·Y1)
|
||||||
|
let t4 := mulmod(x1, y2, P) // 4. t4 ← X1 + Y1 => (X1·Y2)
|
||||||
|
t3 := addmod(t3, t4, P) // 5. t3 ← t3 − t4 => (X2·Y1 + X1·Y2)
|
||||||
|
t4 := mulmod(y2, z1, P) // 6. t4 ← Y2 · Z1 => (Y2·Z1)
|
||||||
|
t4 := addmod(t4, y1, P) // 7. t4 ← t4 + Y1 => (Y2·Z1 + Y1)
|
||||||
|
y3 := mulmod(x2, z1, P) // 8. Y3 ← X2 · Z1 => (X2·Z1)
|
||||||
|
y3 := addmod(y3, x1, P) // 9. Y3 ← Y3 + X1 => (X2·Z1 + X1)
|
||||||
|
t0 := mulmod(3, t0, P) // 10. t0 ← X3 + t0 => (3·(X1·X2))
|
||||||
|
let t2 := mulmod(21, z1, P) // 11. t2 ← b3 · Z1 => (b3·Z1)
|
||||||
|
z3 := addmod(t1, t2, P) // 12. Z3 ← t1 + t2 => (Y1·Y2 + b·3·Z1)
|
||||||
|
t1 := addmod(t1, sub(P, t2), P) // 13. t1 ← t1 − t2 => (Y1·Y2 - b·3·Z1)
|
||||||
|
y3 := mulmod(21, y3, P) // 14. Y3 ← b3 · Y3 => 3·b·(X2·Z1 + X1)
|
||||||
|
x3 := mulmod(t4, y3, P) // 15. X3 ← t4 · Y3 => (Y2·Z1 + Y1)·b·3·(X2·Z1 + X1)
|
||||||
|
t2 := mulmod(t3, t1, P) // 16. t2 ← t3 · t1 => ((X2·Y1 + X1·Y2)·(Y1·Y2 - b3·Z1))
|
||||||
|
x3 := addmod(t2, sub(P, x3), P) // 17. X3 ← t2 − X3 => ((X2·Y1 + X1·Y2)·(Y1·Y2 - b3·Z1) - 3·B·(Y2·Z1 + Y1)·(X2·Z1 + X1))
|
||||||
|
y3 := mulmod(y3, t0, P) // 18. Y3 ← Y3 · t0 => (9·b·(X2·Z1 + X1)·X1·X2)
|
||||||
|
t1 := mulmod(t1, z3, P) // 19. t1 ← t1 · Z3 => (Y1·Y2 - b·3·Z1)·(Y1·Y2 + b·3·Z1)
|
||||||
|
y3 := addmod(t1, y3, P) // 20. Y3 ← t1 + Y3 => ((Y1·Y2 - b·3·Z1)·(Y1·Y2 + 3·b·Z1) + 9·b·(X2·Z1 + X1)·X1·X2)
|
||||||
|
t0 := mulmod(t0, t3, P) // 21. t0 ← t0 · t3 => (3·X2·Y1 + (X2·Y1 + X1·Y2))
|
||||||
|
z3 := mulmod(z3, t4, P) // 22. Z3 ← Z3 · t4 => (Y1·Y2 + b·3·Z1)·(Y2·Z1 + Y1)
|
||||||
|
z3 := addmod(z3, t0, P) // 23. Z3 ← Z3 + t0 => ((Y1·Y2 + b·3·Z1)·(Y2·Z1 + Y1) + 3·X2·Y1·(X2·Y1 + X1·Y2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,6 @@ contract WeaverMock is Weaver {
|
|||||||
address private _previousAddress;
|
address private _previousAddress;
|
||||||
|
|
||||||
constructor(address previousWeaver) {
|
constructor(address previousWeaver) {
|
||||||
Weaver._initialize(previousWeaver);
|
|
||||||
_previousAddress = previousWeaver;
|
_previousAddress = previousWeaver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,10 +61,10 @@ abstract contract Weaver is IWeaver {
|
|||||||
bytes32 left = bytes32(_treeNodes[session][j].upperLookup(atBlock));
|
bytes32 left = bytes32(_treeNodes[session][j].upperLookup(atBlock));
|
||||||
bytes32 right = bytes32(_treeNodes[session][j | 1].upperLookup(atBlock));
|
bytes32 right = bytes32(_treeNodes[session][j | 1].upperLookup(atBlock));
|
||||||
|
|
||||||
bytes32 leftHash = Hashes.efficientKeccak256(left);
|
bytes32 leftHash = Hashes.efficientKeccak256Prefixed(left);
|
||||||
bytes32 rightHash = Hashes.efficientKeccak256(right);
|
bytes32 rightHash = Hashes.efficientKeccak256Prefixed(right);
|
||||||
|
|
||||||
currentLevel[i] = Hashes.efficientKeccak256(leftHash, rightHash);
|
currentLevel[i] = Hashes.efficientKeccak256Prefixed(leftHash, rightHash);
|
||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +73,10 @@ abstract contract Weaver is IWeaver {
|
|||||||
i = 0;
|
i = 0;
|
||||||
for (; i < currentLevelCount;) {
|
for (; i < currentLevelCount;) {
|
||||||
uint256 j = i << 1;
|
uint256 j = i << 1;
|
||||||
bytes32 left = currentLevel[j];
|
bytes32 leftHash = currentLevel[j];
|
||||||
bytes32 right = currentLevel[j | 1];
|
bytes32 rightHash = currentLevel[j | 1];
|
||||||
|
|
||||||
currentLevel[i] = Hashes.efficientKeccak256(left, right);
|
currentLevel[i] = Hashes.efficientKeccak256Prefixed(leftHash, rightHash);
|
||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ abstract contract Weaver is IWeaver {
|
|||||||
|
|
||||||
for (; i < currentLevelCount;) {
|
for (; i < currentLevelCount;) {
|
||||||
bytes32 leaf = bytes32(_treeNodes[session][i].upperLookup(atBlock));
|
bytes32 leaf = bytes32(_treeNodes[session][i].upperLookup(atBlock));
|
||||||
currentLevel[i] = Hashes.efficientKeccak256(leaf);
|
currentLevel[i] = Hashes.efficientKeccak256Prefixed(leaf);
|
||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ abstract contract Weaver is IWeaver {
|
|||||||
bytes32 left = currentLevel[j];
|
bytes32 left = currentLevel[j];
|
||||||
bytes32 right = currentLevel[j | 1];
|
bytes32 right = currentLevel[j | 1];
|
||||||
|
|
||||||
currentLevel[i] = Hashes.efficientKeccak256(left, right);
|
currentLevel[i] = Hashes.efficientKeccak256Prefixed(left, right);
|
||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {Test} from "forge-std/Test.sol";
|
|||||||
|
|
||||||
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
||||||
import {FullMath} from "../../src/libraries/FullMath.sol";
|
import {FullMath} from "../../src/libraries/FullMath.sol";
|
||||||
|
import {Verifier} from "../../src/libraries/Verifier.sol";
|
||||||
import {RequestPacking} from "../../src/libraries/Packing.sol";
|
import {RequestPacking} from "../../src/libraries/Packing.sol";
|
||||||
import {IStorageHistory} from "../../src/interfaces/IStorageHistory.sol";
|
import {IStorageHistory} from "../../src/interfaces/IStorageHistory.sol";
|
||||||
import {StorageHistory} from "../../src/types/StorageHistory.sol";
|
import {StorageHistory} from "../../src/types/StorageHistory.sol";
|
||||||
@ -159,13 +160,9 @@ contract MockStaking is Test {
|
|||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 packed,
|
uint256 packed,
|
||||||
address caller
|
address caller
|
||||||
) external payable {
|
) external {
|
||||||
if (msg.value > 0) {
|
|
||||||
vm.deal(address(gatekeeper), address(gatekeeper).balance + msg.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
vm.prank(address(gatekeeper), caller);
|
vm.prank(address(gatekeeper), caller);
|
||||||
gatekeeper.recall{value: msg.value}(exodusSession, amount, packed);
|
gatekeeper.recall(exodusSession, amount, packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recall(address receiver, uint256 amount) external {
|
function recall(address receiver, uint256 amount) external {
|
||||||
@ -273,10 +270,22 @@ contract GatekeeperTest is Test {
|
|||||||
assert(IStorageHistory(storageHistory).isTransactionExecuted(exodusSession));
|
assert(IStorageHistory(storageHistory).isTransactionExecuted(exodusSession));
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_rotateWork(bytes32 aggregatedPublicKey) public {
|
function test_rotateWork() public {
|
||||||
vm.warp(block.timestamp + 1);
|
vm.warp(block.timestamp + 1);
|
||||||
vm.prank(address(gatekeeper));
|
vm.prank(address(gatekeeper));
|
||||||
gatekeeper.rotate(block.timestamp, aggregatedPublicKey, 0);
|
gatekeeper.rotate(block.timestamp, 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0);
|
||||||
|
|
||||||
|
vm.warp(block.timestamp + 1);
|
||||||
|
vm.prank(address(gatekeeper));
|
||||||
|
gatekeeper.rotate(block.timestamp, 0xF9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9, 0);
|
||||||
|
|
||||||
|
vm.warp(block.timestamp + 1);
|
||||||
|
vm.prank(address(gatekeeper));
|
||||||
|
gatekeeper.rotate(block.timestamp, 0x3590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66, 0);
|
||||||
|
|
||||||
|
vm.warp(block.timestamp + 1);
|
||||||
|
vm.prank(address(gatekeeper));
|
||||||
|
gatekeeper.rotate(block.timestamp, 0xD4E0D4642DB1613B2C94A81FCD34E39A2A31ACD774CD42525A88CF69EBA2E611, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_couldNotBridgeBelowExistential(uint256 amount) public {
|
function test_couldNotBridgeBelowExistential(uint256 amount) public {
|
||||||
@ -297,16 +306,16 @@ contract GatekeeperTest is Test {
|
|||||||
staking.runGhost(bytes32(abi.encodePacked(ALICE)), type(uint104).max);
|
staking.runGhost(bytes32(abi.encodePacked(ALICE)), type(uint104).max);
|
||||||
|
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.updatePublicKeyMetadata(0, 0x875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e4669, 0);
|
gatekeeper.updatePublicKeyMetadata(0, 0x36ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c374, 0);
|
||||||
|
|
||||||
(bytes32 prevPublicKey, uint8 prevParity,) = gatekeeper.latestPublicKeyInfo();
|
(bytes32 prevPublicKey, uint8 prevParity,) = gatekeeper.latestPublicKeyInfo();
|
||||||
|
|
||||||
// genesis validators 4 validators, DKG #0
|
// genesis validators 4 validators, DKG #0
|
||||||
// exodus session #0
|
// exodus session #0
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"49f03a670000000000000000000000000000000000000000000000000000000000000000875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e46690000000000000000000000000000000000000000000000000000000000000000",
|
hex"49f03a67000000000000000000000000000000000000000000000000000000000000000036ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c3740000000000000000000000000000000000000000000000000000000000000000",
|
||||||
hex"044d9fa18df9da04381ed256981570a6ef6a0893496ded966fc994662df931ed423b29e2737394b31d8498594caad7b77e36ab31ac79df3796a1b6f26baa5552ae",
|
0x58a4ef4e4f9cad19e9bb3707a48f01920ba309f69892609b196bbc112b6aebea,
|
||||||
0x24029a571fcaeadd14f4afe8be62afe3d07876ae270c3caf446ecb6cfc7c08f2
|
0x2de1a8116c65a290c51fee3bac24546c09522423640ae0e38f45791b1d81a069
|
||||||
);
|
);
|
||||||
|
|
||||||
(bytes32 publicKey, uint8 parity, uint64 session) = gatekeeper.latestPublicKeyInfo();
|
(bytes32 publicKey, uint8 parity, uint64 session) = gatekeeper.latestPublicKeyInfo();
|
||||||
@ -317,17 +326,17 @@ contract GatekeeperTest is Test {
|
|||||||
// could not apply signature from DKG #2
|
// could not apply signature from DKG #2
|
||||||
vm.expectRevert();
|
vm.expectRevert();
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"49f03a6700000000000000000000000000000000000000000000000000000000000000133492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000",
|
hex"49f03a6700000000000000000000000000000000000000000000000000000000000000135353a4ce3430b37cabb7c495aabfec94895183672738873f4b227bf4ce31fbe50000000000000000000000000000000000000000000000000000000000000000",
|
||||||
hex"0434c3b37293516c6204dc291821e19ab5b3d8afb0947a0a2dffc91600fbd3f6b9783a66887d515e774b98a63a35a08bb3d914407fd768e92020b0ebaa3c8602b3",
|
0xd1e4b50b4ff3e9b98ce17b375d6007cf0cf9d65e795cbe682609c1343361a81c,
|
||||||
0x71cd57e697af70f84a960cc94fcbae5889efbf919df410282a04c6d19f92609e
|
0x0cdd6c13658d862e7f816c59ad9cb1b6f5b3b981f019e698f27d1a354dc69cd5
|
||||||
);
|
);
|
||||||
|
|
||||||
// genesis validators 7 validators, DKG #1
|
// genesis validators 7 validators, DKG #1
|
||||||
// exodus session #11
|
// exodus session #11
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"49f03a67000000000000000000000000000000000000000000000000000000000000000b4e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e1570000000000000000000000000000000000000000000000000000000000000000",
|
hex"49f03a67000000000000000000000000000000000000000000000000000000000000000bb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de60000000000000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04b51db09ec2f4bebdb65c5352efa75f8d07088408e3ff907c74b0d7928a40dbe06f864364a3e6d219849ca8e7d47e6c66f8a18ca9f4fa4752df13bb6c2eae1172",
|
0x993fc0c870e1010f4933cbdb17b4539aea07234ff787eb3185d03ef8c0d2787e,
|
||||||
0x072e625bdd3ff7d09f2bf896b5e261efa007f8d81a9e2c828525ec74bd3ee08d
|
0x4bfe369753a3125a37d13db08ea9125fe2280b70aa47e5890bf9401c785bdb92
|
||||||
);
|
);
|
||||||
|
|
||||||
(publicKey, parity, session) = gatekeeper.latestPublicKeyInfo();
|
(publicKey, parity, session) = gatekeeper.latestPublicKeyInfo();
|
||||||
@ -341,9 +350,9 @@ contract GatekeeperTest is Test {
|
|||||||
// genesis validators 5 validators, DKG #2
|
// genesis validators 5 validators, DKG #2
|
||||||
// exodus session #19
|
// exodus session #19
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"49f03a6700000000000000000000000000000000000000000000000000000000000000133492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000",
|
hex"49f03a6700000000000000000000000000000000000000000000000000000000000000135353a4ce3430b37cabb7c495aabfec94895183672738873f4b227bf4ce31fbe50000000000000000000000000000000000000000000000000000000000000000",
|
||||||
hex"0434c3b37293516c6204dc291821e19ab5b3d8afb0947a0a2dffc91600fbd3f6b9783a66887d515e774b98a63a35a08bb3d914407fd768e92020b0ebaa3c8602b3",
|
0xd1e4b50b4ff3e9b98ce17b375d6007cf0cf9d65e795cbe682609c1343361a81c,
|
||||||
0x71cd57e697af70f84a960cc94fcbae5889efbf919df410282a04c6d19f92609e
|
0x0cdd6c13658d862e7f816c59ad9cb1b6f5b3b981f019e698f27d1a354dc69cd5
|
||||||
);
|
);
|
||||||
|
|
||||||
(publicKey, parity, session) = gatekeeper.latestPublicKeyInfo();
|
(publicKey, parity, session) = gatekeeper.latestPublicKeyInfo();
|
||||||
@ -351,23 +360,22 @@ contract GatekeeperTest is Test {
|
|||||||
assertEq(parity, prevParity);
|
assertEq(parity, prevParity);
|
||||||
assertEq(session, 19);
|
assertEq(session, 19);
|
||||||
|
|
||||||
|
|
||||||
uint256 aliceAmountBefore = staking.recalledAmount(ALICE);
|
uint256 aliceAmountBefore = staking.recalledAmount(ALICE);
|
||||||
uint256 bobAmountBefore = staking.recalledAmount(BOB);
|
uint256 bobAmountBefore = staking.recalledAmount(BOB);
|
||||||
uint256 aliceBalanceBefore = ALICE.balance;
|
uint256 aliceBalanceBefore = ALICE.balance;
|
||||||
uint256 bobBalanceBefore = BOB.balance;
|
uint256 bobBalanceBefore = BOB.balance;
|
||||||
|
|
||||||
// execute bridge out, happened on DKG #0
|
// execute bridge out, happened on DKG #1
|
||||||
// amount: 69; commission: 0%; ALICE
|
// amount: 34; commission: 0%; ALICE
|
||||||
// exodus session #1
|
// exodus session #1
|
||||||
vm.prank(ALICE, ALICE);
|
vm.prank(ALICE, ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000010000000000007a6900000000",
|
hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000010000000000007a6900000000",
|
||||||
hex"04bccb4cd4633e2c61ca5c65006a6a09baa893be219b21509866123a8d6299f92aefe9c380bd9728dbe0b93a8042f431636d08ed191b5c04062bf14e1347059cb9",
|
0x74e1ee0256e3a1f6c38744fff8d72ffb905d660679e69c76b0af2e75db9fbfcc,
|
||||||
0xe579753d931a78b143d7e3d86e1117ccbc9d2d7357b0207ea682046a0b06d798
|
0x4c512ab429d8c38a199daaa7f2c3d74956d2ff435871b160946b69804a1e5d54
|
||||||
);
|
);
|
||||||
|
|
||||||
assertEq(aliceAmountBefore + 69, staking.recalledAmount(ALICE));
|
assertEq(aliceAmountBefore + 34, staking.recalledAmount(ALICE));
|
||||||
assertEq(bobAmountBefore, staking.recalledAmount(BOB));
|
assertEq(bobAmountBefore, staking.recalledAmount(BOB));
|
||||||
assertEq(aliceBalanceBefore, ALICE.balance);
|
assertEq(aliceBalanceBefore, ALICE.balance);
|
||||||
assertEq(bobBalanceBefore, BOB.balance);
|
assertEq(bobBalanceBefore, BOB.balance);
|
||||||
@ -379,139 +387,138 @@ contract GatekeeperTest is Test {
|
|||||||
aliceBalanceBefore = ALICE.balance;
|
aliceBalanceBefore = ALICE.balance;
|
||||||
bobBalanceBefore = BOB.balance;
|
bobBalanceBefore = BOB.balance;
|
||||||
|
|
||||||
uint256 buyback = 220;
|
// TODO: revisit
|
||||||
|
// execute bridge out, happened on DKG #2
|
||||||
// execute bridge out, happened on DKG #1
|
// amount: 210; commission: 50%; BOB
|
||||||
// amount: 420; commission: 50%; BOB
|
|
||||||
// exodus session #12
|
// exodus session #12
|
||||||
vm.prank(ALICE, ALICE);
|
vm.prank(ALICE, ALICE);
|
||||||
gatekeeper.verify{value: buyback}(
|
gatekeeper.verify(
|
||||||
hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000020000000000007a6980000000",
|
hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000020000000000007a6980000000",
|
||||||
hex"049f458500a78f56420380f0c6863905f1181e705f6b562eb469bd81a03676a2d9b436a53d2356ea0a5bb175ca837655fab8114c6e64cfdd47f3d36d1a945d7122",
|
0x99c5f02bf312fc6b1a125b83397aa87df369738f85275bc42d249660abb1f0e1,
|
||||||
0x772731b359ee7ecac7830438333e4ffb61759b36610f69cef20f66f7a79a405f
|
0x8326ee3fc1cbb1421e2c974d6cc7cb2bfdc9c4f6ebfd403363f6b3a3bc8e9bef
|
||||||
);
|
);
|
||||||
|
|
||||||
assertApproxEqAbs(aliceAmountBefore + 210, staking.recalledAmount(ALICE), 1);
|
assertApproxEqAbs(aliceAmountBefore + 105, staking.recalledAmount(ALICE), 1);
|
||||||
assertApproxEqAbs(bobAmountBefore + 210, staking.recalledAmount(BOB), 1);
|
assertApproxEqAbs(bobAmountBefore + 105, staking.recalledAmount(BOB), 1);
|
||||||
|
|
||||||
// execute setDistributor, exodusSession: 2
|
// execute setDistributor, exodusSession: 2
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000020000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002475619ab5000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000020000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002475619ab5000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"049f222e7ec776c390c7fe96b9c2034c37f4fc71a9714588a5d98ccb50dc748c98fe375c628e7bcc4db4f204a2a168b22ecbc631616a69987ef42601ad239b2ab5",
|
0x45a9889cb48e0eca44c3add96dc68d6ab728c1a7e4eab14323f0dcfe67472c1f,
|
||||||
0x515539c5b713900a4dd4b3b119b22a47f862c90fdff9da91ed3fca687ea8db06
|
0x40e6980e96efc0fc6acf47aa0cd665bc5d85a01b909fc4d960948c76f45723b4
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute setWarmupPeriod, exodusSession: 3
|
// execute setWarmupPeriod, exodusSession: 3
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000030000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a85667c5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000030000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a85667c5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04c2d9b903c0bd640ff858de3518c64965e2ff07215a131c85a8febec629999cfd60970a3a99d0d04ba08a334f2aa865842ebde37407c6fee2b17f820c8104fc88",
|
0x356ef46cfd654b0b609bdff33147df25c20ff9ca7ac3334c57f12e99b6248112,
|
||||||
0xe1727e132cbb7502a60bab56c5dedce1abca8130792ddd6d9ba59918766688e8
|
0xa6363286f97c02a39aa5280d74f8dc02dabd078911eef60e4848b7d5deeb325b
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute setBounty, exodusSession: 4
|
// execute setBounty, exodusSession: 4
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000040000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000245d87d363000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000040000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000245d87d363000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04ec7d454696833a1c9c04d79be81e0dfe8a4791862f1dc5d4e908338df30621911fb182e6f204699c53ea5b11db1c855f55dfd149d4882a80afa437d80c58d9cd",
|
0xe6a419a5314afed1ff25df0cbf76f2002bfa9d7746817670f2487be5d7774118,
|
||||||
0x22d3138ed4e72f104c5d86814c1b4e6eeed39cdcf97e087effe33f860d06f133
|
0x7ce4c7207efdfdb9c71b26c7dd071572544fb27a329b348379d70b2e7a5f21fc
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute setAdjustment, exodusSession: 5
|
// execute setAdjustment, exodusSession: 5
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000050000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006446d36ab5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000050000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006446d36ab5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"0484819be6cb8879179f91aaf94c1513234d9068052dd42bf067606033c2d173efe85e87acf5bc1020cab6ec67d5ec8f7b237c5f315b825b56e915e4736c2b7b62",
|
0x649a51e565d154f549e24aaf400ed9a2bb8812ed87eeac36372f36ac8cd6aa34,
|
||||||
0x865b1e9006973e8b5b5492f2f6a0c85ee69ee7ae72f714ee076035865cd26a72
|
0xc9decb2fa41d9217f9a609d568f86bf92b66d6a91ed3c34031025d3845e34b09
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute updateGatekeeperAddress, exodusSession: 6
|
// execute updateGatekeeperAddress, exodusSession: 6
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000060000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002484f157cd000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000060000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002484f157cd000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"040bfec065e85cb245d891a94b50b12ea8f91d27a90e113c0bf47f93e76c0c21380e6ff8dc05406d1e8ec34b2c90cc345fea1245c1ca3eb7ecccd8606bfb334f76",
|
0xb445285e36eb120a47bd995ce7ecc07f73bf1ec99b5024ef14e87aa1bffd8b39,
|
||||||
0x15141679af9a42a9228adc686f802fe183515180bed3de3933e1622668e06796
|
0x8f7241cd388505b0f964dd54243c968559ba603400ee71dea0738a9084f5cf50
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute addPool, exodusSession: 7
|
// execute addPool, exodusSession: 7
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000070000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024d914cd4b000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000070000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024d914cd4b000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04eb497652f4ad64ddd9223cd1af4785b37c6b2a41f8c1f54b906d595ab0d2b53305cd006238ca4eaf7eede77b3e2c0d1019e9f9d505fe80e86240e0d83051dcf2",
|
0x83cdbf2cee6f13d60c2261feed4d0643e847cfba6af316722538281c9cb433c8,
|
||||||
0xa93dcb9c9c399973a17abc3b3667e37da716bdd5e9ed9c0b99d9fc869a886700
|
0xdd0c8c1d6d154c951a4171ff9a40084afbfe5f7b3c70c0521e5b6605310e77cb
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute removePool, exodusSession: 8
|
// execute removePool, exodusSession: 8
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000080000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a38dcbd0000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000080000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a38dcbd0000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000",
|
||||||
hex"0446039e3eec08f356c0a6e9fdd243aed6d840c1d9d973d1496db70499061055d45faf8e945d2fb87016cdcfda040df8fcaf22fe9a466dbdd4687cbfde7c87d0d8",
|
0x622a8a5d57b10682a90e1b92f797375a6bcbb78f30c45877ea570091af1b2831,
|
||||||
0x110eedf82f6533d95a43a19de3da026c51557e552bd4c5b6f06ca94d6ab2c8db
|
0xd72cd8354a7be788b801e19994a8155f3938ef58005095b398bc96cd2dc77166
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute close, exodusSession: 9
|
// execute close, exodusSession: 9
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000090000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000240aebeb4e00000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000090000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000240aebeb4e00000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
||||||
hex"048da83909e645cf4313d00985c86bcbd24f584512f2279476767fb94829a2a9c7b95bcfeacc3bee2fe4710bfc2bcf2e72e58bcd37fc02293b660a7b70e2efd184",
|
0x0ad9c560affebaea5c589fe831033bac2d9c828aacf58559bbf5b2d00f7842b2,
|
||||||
0x8a28d3b7b5db6564e4abb846bc662a69d9b52ed08bd2ce2dbc6af4e86167f55e
|
0x10121ffe0cc95cf3cbb4e92d72d61feec3e94045185cd7f3c5ce0d01e3a644ea
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute close, exodusSession: 10
|
// execute close, exodusSession: 10
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"31371426000000000000000000000000000000000000000000000000000000000000000a0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000144a0139f41000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000000005390000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
hex"31371426000000000000000000000000000000000000000000000000000000000000000a0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000144a0139f41000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000000005390000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"0417bd8b7509486284c1f613117c61abc39cee8a24422fce457099e430b805468be33547f272d8123e9aa6f8895babbaa3a3731eaeda7d8ad4286c9fb117034d21",
|
0xb354049d0012ef7ec3edac6aba453daf4bdc2d28fe1d88138f94459799e2343f,
|
||||||
0x0b71c4d8ca7748ec35257a42f26e09aaab9fa4a03e40d50a96bfdfdce10ce7e5
|
0x13a6f8b10007b41fa08c8efee85501fac2554571af99fe587b534fe28fdb82a3
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute enable, exodusSession: 13
|
// execute enable, exodusSession: 13
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"31371426000000000000000000000000000000000000000000000000000000000000000d0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064e4e33ef800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
hex"31371426000000000000000000000000000000000000000000000000000000000000000d0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064e4e33ef800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04f34417b947a4da097ca9596838430bf40587339fb42a09210ceb0dbbcfd98a99b1e8fd8f4d2301ee5b5d304e1d8b8e8b81ac14688f1e7de41d65c09a65975f01",
|
0x0716f763060cfd52339544a203d0e156a42370b0e22d78ea9bf8766b0b66682b,
|
||||||
0xa4084ea553df2f808c86437547550be910554d41d33a5d66a4643c9792c4f56f
|
0xc2da93948f869c5102992bd1cbd70ef5f821ff522305c69d113faf2e89570ce7
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute disable, exodusSession: 14
|
// execute disable, exodusSession: 14
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"31371426000000000000000000000000000000000000000000000000000000000000000e0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044529918310000000000000000000000000000000000000000000000000000000000000003000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
hex"31371426000000000000000000000000000000000000000000000000000000000000000e0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044529918310000000000000000000000000000000000000000000000000000000000000003000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04f94dad10974c9f0b9307444dc4c660f1f169b25fd3ed9fd563df74714e73c2d4e92b3429505989327d449d9a68e6cce0f557574c92c0ca7bc8126dd710094e9e",
|
0x7ed91b176c29b73a077e51de0c2a12f6df5e7e04862eb07f9c393f6fc1cd3a8f,
|
||||||
0xb6b75ed763f4d06b9d7a7557ca8d095df656ca25db74645fb47a0b45d27ec501
|
0x798563362adaade33f39266bb3fa233ac9161ca55d532ca65d5b6d4d0f1edbd2
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute forfeitReserves, exodusSession: 15
|
// execute forfeitReserves, exodusSession: 15
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"31371426000000000000000000000000000000000000000000000000000000000000000f0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064f0de236c000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
hex"31371426000000000000000000000000000000000000000000000000000000000000000f0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064f0de236c000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04af06146f4ca63ef11b82ad891d8e03525a11922316a7dd3f71ff4b6aa5ee6793d29e6af2355d26bc173bb52c1f5eb7d8b279ed40bef2d1cd521da33517b6d3cd",
|
0x7f90802deb959f3bea4aa2cda26dad5ec601fc6e45dcd941a19ee9ff57e3f571,
|
||||||
0x6343b047bb8fe39200758de1e874ddfaf296e1f9259f0b720a070a69e7a3ee08
|
0xf61bb645ce15a7e4d0a693e0e4defe1f58fa1b113818a083b582fce05ec728f5
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute redeemReserve, exodusSession: 16
|
// execute redeemReserve, exodusSession: 16
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000100000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004482a21577000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000100000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004482a21577000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
||||||
hex"041ff894074000f2d934cf3b136165766044b177e69de4c36fac4d1265b855e1a5b4b7b2b25400fbf4d5eb4619039ffc95555db216991d3050bb6fd966f6e3eeab",
|
0x197fd53cb6c9c89e8689419c2ea745233487ba7666f896a2469fc5269c785160,
|
||||||
0x7d31ebf1e510616e541795b6448d387d2119b3fdd0124e5116c53726b6b1cc15
|
0x79480d2dfee9c8dcdc2a28a22b3d49ed193c912390c0be655253028fd8ca883d
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute withdraw, exodusSession: 17
|
// execute withdraw, exodusSession: 17
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000110000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044f3fef3a3000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000110000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044f3fef3a3000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000",
|
||||||
hex"04f31030cf8563dd976d1a823a84e43ebdcc13bb5e5e0d7a2ff372006c71e6ab3d4d0770771682dcd6eff9e13fb3d113b484d7384d08f247760b07149dca1aa234",
|
0x53a249b4952662c3a86a810cff1e530ba354761e4091dee9a8997279160b017b,
|
||||||
0x06aad271d98e69d1ff18bf39e6713f347aba0df04d99bc4a9304b780431d12ae
|
0x8042a9b2521d07612ef0fdccaa98ce9561914b20bf75af49310fc36c240073c7
|
||||||
);
|
);
|
||||||
|
|
||||||
// execute auditReserves, exodusSession: 18
|
// execute auditReserves, exodusSession: 18
|
||||||
vm.prank(ALICE);
|
vm.prank(ALICE);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"3137142600000000000000000000000000000000000000000000000000000000000000120000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000042b7ce50000000000000000000000000000000000000000000000000000000000",
|
hex"3137142600000000000000000000000000000000000000000000000000000000000000120000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000042b7ce50000000000000000000000000000000000000000000000000000000000",
|
||||||
hex"049e5d54fd32dcec64b20943a61763dc760b1e3e9d31948780e2193480d904984c0cdaa8074196c06104557b1a04de6aeeda135e0c3413192f9e4331f3b7447ff2",
|
0xf1f4d62d27c3d0388b2298b621b23cd5791e1b97d4423ffc16b14e81ff0df97c,
|
||||||
0x43ed5301b16b4b2bc91c28dcfbaecc9949a7fc8fe5c57dfef6229f62493da6d2
|
0xdbeed3eb94a829710147595c1b10f2ac6ec761c9721d8cc4711842c212ac517e
|
||||||
);
|
);
|
||||||
|
|
||||||
address storageHistory = gatekeeper.storageHistory();
|
address storageHistory = gatekeeper.storageHistory();
|
||||||
|
|||||||
@ -8,15 +8,10 @@ import {Ghost} from "../../src/GhstERC20.sol";
|
|||||||
import {GhostAuthority} from "../../src/GhostAuthority.sol";
|
import {GhostAuthority} from "../../src/GhostAuthority.sol";
|
||||||
import {GhostTreasury} from "../../src/Treasury.sol";
|
import {GhostTreasury} from "../../src/Treasury.sol";
|
||||||
import {GhostStaking} from "../../src/Staking.sol";
|
import {GhostStaking} from "../../src/Staking.sol";
|
||||||
import {GhostBondDepository} from "../../src/BondDepository.sol";
|
|
||||||
import {ERC20Mock} from "../../src/mocks/ERC20Mock.sol";
|
|
||||||
import {WETH9} from "../../src/mocks/WETH9.sol";
|
import {WETH9} from "../../src/mocks/WETH9.sol";
|
||||||
import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol";
|
import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol";
|
||||||
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
import {Gatekeeper} from "../../src/Gatekeeper.sol";
|
||||||
|
|
||||||
import {ITreasury} from "../../src/interfaces/ITreasury.sol";
|
import {ITreasury} from "../../src/interfaces/ITreasury.sol";
|
||||||
import {IGatekeeper} from "../../src/interfaces/IGatekeeper.sol";
|
|
||||||
import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
|
|
||||||
|
|
||||||
contract GatekeeperRecallTest is Test {
|
contract GatekeeperRecallTest is Test {
|
||||||
uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000;
|
uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000;
|
||||||
@ -100,7 +95,8 @@ contract GatekeeperRecallTest is Test {
|
|||||||
function test_recallChainWorks() public {
|
function test_recallChainWorks() public {
|
||||||
vm.startPrank(INITIALIZER);
|
vm.startPrank(INITIALIZER);
|
||||||
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper()));
|
||||||
gatekeeper.updatePublicKeyMetadata(0, 0x4e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e157, 0);
|
gatekeeper.updatePublicKeyMetadata(0, 0x36ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c374, 0);
|
||||||
|
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
vm.startPrank(ALICE);
|
vm.startPrank(ALICE);
|
||||||
@ -126,9 +122,9 @@ contract GatekeeperRecallTest is Test {
|
|||||||
vm.txGasPrice(2 gwei);
|
vm.txGasPrice(2 gwei);
|
||||||
vm.startPrank(BOB, BOB);
|
vm.startPrank(BOB, BOB);
|
||||||
gatekeeper.verify(
|
gatekeeper.verify(
|
||||||
hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000009536c70891000000000000000000000000000000000000000000020000000000007a6980000000",
|
hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000007a919134c0400000000000000000000000000000000000000000010000000000007a6900000000",
|
||||||
hex"046566d4b0904bf35afd25dff583d53bd30e50f57cc790ad08377e0b85006b38b85046b527098f3dfdadc30d6623b6b1c4644306dd56d39f7c9d6b3b295d005c33",
|
0x938640689e6f52929acf2714c5c785e8e725b5df616c449a19bca8a8b300ec8b,
|
||||||
0x942fb44ad0422c197f9c3016ff7c7e574a9f86182c5485e39fc9bebf61228ad6
|
0x15b8b8c2934ee96d6a83a24055d83ea4074d251c207584e66d9caf8d653cabf2
|
||||||
);
|
);
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
|
|
||||||
|
|||||||
@ -95,14 +95,14 @@ contract GatekeeperWeaver is Gatekeeper {
|
|||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
computedHash = Hashes.efficientKeccak256(computedHash);
|
computedHash = Hashes.efficientKeccak256Prefixed(computedHash);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (; i < proof.length; ) {
|
for (; i < proof.length; ) {
|
||||||
if (slotIndex % 2 == 0) {
|
if (slotIndex % 2 == 0) {
|
||||||
computedHash = Hashes.efficientKeccak256(computedHash, proof[i]);
|
computedHash = Hashes.efficientKeccak256Prefixed(computedHash, proof[i]);
|
||||||
} else {
|
} else {
|
||||||
computedHash = Hashes.efficientKeccak256(proof[i], computedHash);
|
computedHash = Hashes.efficientKeccak256Prefixed(proof[i], computedHash);
|
||||||
}
|
}
|
||||||
slotIndex >>= 1;
|
slotIndex >>= 1;
|
||||||
unchecked { ++i; }
|
unchecked { ++i; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user