Skip to content

Treasury

Reference for Treasury.sol — the buyback-burn sink. It receives forfeited TIDE whose lottery prize expired un-activated, and the only thing anyone can ever do with that TIDE is burn it. There is no withdrawal path. For the narrative (“the dev holds the button, not the cash”) see ../mechanics/treasury.md.

FieldValue
ContractTreasury
Sepolia address0x076f29063199DB470D260E5cE2cb560Af98cfBd3
Constructed byTideHook constructor — treasury = new Treasury(address(this), _owner)
tidethe TideHook address (the TIDE ERC-20, which exposes a treasury-only burn)
guardian (initial)the TideHook owner / deployer

See ../deployment/addresses.md for all addresses.

ITideBurn public immutable tide; // the TIDE token (the hook)
address public guardian; // may trigger burns and hand off the role; never custodial
  • tide is set once at construction and can never change.
  • guardian is the only privileged role. It can burn and re-assign itself — nothing else.

The Treasury is a sink, not a participant. TIDE reaches it through exactly one routine path: a lottery prize that expired un-activated.

When a holder sells or transfers a Tide-LP NFT before their vesting completes, the unvested remainder is forfeited and raffled to another holder as a pending prize (see ../mechanics/lottery.md). The winner has a bounded window (prizeActivationWindow) to activate it. If they don’t, anyone may permissionlessly call expirePrize(winner) on the hook, which transfers the stale prize to the Treasury:

// TideHook.expirePrize(address winner) — after the activation window elapses
_transfer(address(this), address(treasury), amount);
emit PrizeExpired(winner, amount);

The forfeit/redistribution flow can also route to the Treasury as a fallback when no eligible winner is found and there are no live shares to redistribute to. The receive() function also accepts raw ETH, but no standard flow sends ETH here — and, critically, there is no path to send it back out.

function executeBuyback() external onlyGuardian

Burns all TIDE currently held by the Treasury. This is the only outward action the contract can take.

uint256 bal = tide.balanceOf(address(this));
if (bal > 0) tide.burn(bal);
emit BuybackBurned(bal);

tide.burn(bal) is the hook’s treasury-gated burn — it reverts TreasuryOnly() for any other caller and only ever burns the Treasury’s own balance, never user funds:

TideHook.burn
function burn(uint256 amount) external {
if (msg.sender != address(treasury)) revert TreasuryOnly();
_burn(address(treasury), amount);
}

Burning reduces total TIDE supply, raising every remaining holder’s share of the pool. The guardian controls only the timing of this reduction; it gains nothing from calling it.

function transferGuardian(address to) external onlyGuardian

Hands off the guardian role (for example to a multisig or timelock). Reverts ZeroGuardian() if to is the zero address. Emits GuardianTransferred(from, to). The new guardian inherits the same single power: it can only burn.

function pendingBurn() external view returns (uint256)

Returns tide.balanceOf(address(this)) — the TIDE currently queued for burning. The dapp surfaces this as “queued to burn” (see ../dapp/overview.md).

EventEmitted byMeaning
BuybackBurned(uint256 tideBurned)executeBuyback()The Treasury’s full TIDE balance was burned (amount may be 0).
GuardianTransferred(address indexed from, address indexed to)transferGuardian()The guardian role was reassigned.
ErrorCondition
GuardianOnly()A guarded function was called by an address other than guardian.
ZeroGuardian()transferGuardian() was passed the zero address.

See events-and-errors.md for the protocol-wide catalogue.

The entire state-changing surface of this contract is two functions: executeBuyback() and transferGuardian(). Neither transfers value to the guardian or any chosen recipient — one burns, the other re-assigns a role whose only power is to burn. There is no withdraw, no sweep, no onlyGuardian escape hatch, and the receive() function has no matching outflow. The guardian holds the button, not the cash.

For the full trust model and the limitations TIDE discloses openly, see ../security/trust-model.md and ../security/known-limitations.md.