o2-tools 0.4.7-rc5

Reusable tooling for trade account and order book contract interactions on Fuel
//! The digest the prop margin pool's expiry cosigner signs.
//!
//! Mirrors `expiry_cosign_digest` in `contracts/prop-margin-pool/src/main.sw`
//! byte for byte. The two change together or every settlement stops
//! verifying; the ABI doc on `expire_or_rollover` says why the figures are
//! signed at all.

use fuels::{
    crypto::Message,
    types::ContractId,
};
use sha2::{
    Digest,
    Sha256,
};

/// Domain tag. Distinct from prop-account's `0x02`, so a signature issued for
/// one contract's cosigner cannot be replayed at the other even when the same
/// key sits behind both.
const EXPIRY_COSIGN_TAG: u8 = 0x03;

/// `sha256(tag ++ chain_id ++ pool ++ account ++ session_id ++ expires_at ++
/// outside ++ roll)`, integers big-endian, ids as their raw 32 bytes and the
/// decision as a single `0`/`1` byte.
pub fn generate_pool_expiry_digest(
    chain_id: u64,
    pool: ContractId,
    account: ContractId,
    session_id: u64,
    expires_at: u64,
    outside: u64,
    roll: bool,
) -> [u8; 32] {
    let mut bytes = Vec::with_capacity(1 + 8 + 32 + 32 + 8 + 8 + 8 + 1);
    bytes.push(EXPIRY_COSIGN_TAG);
    bytes.extend_from_slice(&chain_id.to_be_bytes());
    bytes.extend_from_slice(pool.as_slice());
    bytes.extend_from_slice(account.as_slice());
    bytes.extend_from_slice(&session_id.to_be_bytes());
    bytes.extend_from_slice(&expires_at.to_be_bytes());
    bytes.extend_from_slice(&outside.to_be_bytes());
    bytes.push(u8::from(roll));
    Sha256::digest(&bytes).into()
}

/// The same digest as a signable message: the pool recovers with
/// `Message::from(digest)`, so the payload is the digest itself.
pub fn generate_pool_expiry_signing_payload(
    chain_id: u64,
    pool: ContractId,
    account: ContractId,
    session_id: u64,
    expires_at: u64,
    outside: u64,
    roll: bool,
) -> Message {
    Message::from_bytes(generate_pool_expiry_digest(
        chain_id, pool, account, session_id, expires_at, outside, roll,
    ))
}