Skip to Content
wstGBP is live on Ethereum mainnet. All addresses in these docs are verifiable on-chain.
Contract Reference

Contract Reference

All addresses are Ethereum mainnet (chainId 1) and verifiable on a block explorer.

Token

FieldValue
NameWren Staked tGBP
SymbolwstGBP
Decimals18
Address0x57C3571f10767E49C9d7b60feb6c67804783B7aE
Underlying (gem)tGBP (0x27f6c8289550fCE67f6B50BeD1F519966aFE5287)

Module addresses

The token holds six module references. Proxy modules are bound at their proxy address; the implementation is where the logic (and event ABI) lives.

RefRoleProxyImplementation
gemUnderlying (tGBP)0x27f6c8289550fCE67f6B50BeD1F519966aFE5287n/a
pipPrice oracle0x6A79dCe61A12aa4b75449e0B03746260765D07dF0x44BFEB1110bA6091034DBaAb450eF1e7469fF072
actMarket gate0xB59cB4d3075a8ce5013C78e8Bd7aDA3Fd1300f7f0x635dbb7841c27c74b6bDbf1BEd548aAe2C6C9D77
admTreasury0xa8F5bE8457D6ed5c659647fa8d107C3F2086626A0x192575eeb42644a8014eB545c69f5125e2437A56
copBan-list screen (inherited from tGBP)0x794cF5948444b14105587455EbE96Caace036d520x3bb8eBb11816e1C20c3Db57e2E7e5b421b159255
floOutput conduit0x57C3571f10767E49C9d7b60feb6c67804783B7aE (= token)n/a
n/aMulticall30xcA11bde05977b3631167028862bE2a173976CA11n/a

Compiled with Solidity 0.8.34 (pragma floor ^0.8.28). Source is verified on Etherscan at the addresses above; the deployed contracts are covered by the independent Prototech Labs audit report.

View functions for integrators

FunctionReturnsNotes
navprice()uint256Raw oracle NAV price (WAD).
mintcost()uint256NAV adjusted up by bpsin (0 for wstGBP). Use directly to quote mints.
burncost()uint256NAV adjusted down by bpsout (25 = 0.25%). Use directly to quote redeems.
mintable()boolWhether minting is currently open.
burnable()boolWhether redeeming is currently open.
capacity()uint256Max total supply (effectively unbounded for wstGBP).
cooldown()uint256Redemption delay in seconds (currently 0, so redeems are atomic).
totalSupply()uint256wstGBP in circulation.
balanceOf(address)uint256wstGBP balance.
gem()addressThe underlying token (tGBP).
redemptionCount()uint256Number of redemptions ever opened.
redemptions(uint256)(uint256 amount, address redeemer, uint96 date)A queued redemption by id.
canPass(address)boolScreening pre-check: whether the address passes the cop ban-list screen. Check before submitting instead of catching NotAuthorized.
terms()stringOn-chain pointer to the current terms document.
nonces(address)uint256Current EIP-2612 permit nonce for the owner.
DOMAIN_SEPARATOR()bytes32EIP-712 domain separator used by permit.

Gate (act) schedule reads

mintable() / burnable() on the token are derived from a time window configured on the market gate. The gate exposes the window itself. Call these on the act proxy 0xB59cB4d3075a8ce5013C78e8Bd7aDA3Fd1300f7f (the token does not forward them):

FunctionReturnsNotes
openMint() / haltMint()uint256Unix timestamps bounding the mint window.
openBurn() / haltBurn()uint256Unix timestamps bounding the redeem window.
nextOpenMint() / nextHaltMint()uint256The upcoming mint-window transition, if any (see sentinels below).
nextOpenBurn() / nextHaltBurn()uint256The upcoming redeem-window transition, if any (see sentinels below).
bpsin() / bpsout()uint256Mint / redeem fee in basis points (currently 0 / 25).

The next* reads have two sentinel values, not one: 0 means the boundary is already in the past (no transition ahead), and type(uint256).max means the transition is never scheduled. Under the current mainnet config the market is open indefinitely, so nextOpen*() returns 0 and nextHalt*() returns type(uint256).max. Treat both as “no date to show”, never render them as timestamps.

Useful for UIs that show when the market opens next instead of a bare closed state; see the Gate snippet.

Write functions

FunctionSignatureNotes
mintmint(uint256 amt) returns (uint256 _out)Pull amt tGBP, mint wstGBP. Requires prior tGBP approve.
redeemredeem(uint256 amt) returns (uint256 _id)Burn amt wstGBP; settles tGBP atomically when cooldown 0.
exitexit(uint256 id) returns (uint256 _out)Settle a queued redemption once claimable (cooldown > 0 only).
smeltsmelt(uint256 amt)Burn your own wstGBP without redeeming (no tGBP out). Emits Smelted.
settlesettle() returns (uint256 _out)Sweep surplus tGBP (balance above pending claims) to the output conduit flo. Emits Settled.

Standard ERC-20 (transfer, approve, transferFrom, allowance) and EIP-2612 permit are also available, plus a one-argument approve(address) overload that sets max allowance. All user-facing calls, including smelt(uint256) and settle() above, are screened against tGBP’s ban list via the cop module (see Architecture); there is no allowlist and no administrative approval step.

issue(uint256) and the two-argument smelt(address, uint256) are issuer-only supply operations, and proxy/oracle administration is owner-gated. These are on-chain governance functions, not part of normal integration. (The one-argument smelt(uint256) self-burn above is callable by any holder.) See Privileged surface.

EIP-2612 permit

permit(owner, spender, value, deadline, v, r, s) accepts a standard EIP-712 Permit signature (Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)) over this domain:

const domain = { name: 'Wren Staked tGBP', version: '1', chainId: 1, verifyingContract: '0x57C3571f10767E49C9d7b60feb6c67804783B7aE', } as const

Read the owner’s current nonce from nonces(owner). permit is ban-list screened like everything else: the submitting relayer (msg.sender), the owner, and the spender must all pass the cop screen.

Events

event ContractCreated(address indexed creator, uint256 indexed price, uint256 indexed amount); event ContractRedemption(uint256 indexed id, uint256 indexed date, address indexed redeemer, uint256 amount); event ClaimProcessed(uint256 indexed id, address indexed claimer, uint256 indexed amount); event Settled(address indexed conduit, uint256 indexed amount); // settle() swept surplus tGBP to flo event Issued(address indexed issuer, uint256 indexed amount); // issuer mint (no tGBP in) event Smelted(address indexed smelter, uint256 indexed amount); // burn without redemption // plus standard ERC-20 Transfer / Approval

Errors

Custom errors thrown by the token. Decode them to show users why a call reverted (the subgraph indexes the corresponding lifecycle events):

ErrorThrown when
MarketClosed()mint while mintable() is false, or redeem while burnable() is false.
InvalidPrice()The oracle reads 0 (navprice() == 0); quoting is paused.
DustThreshold(uint256 min)mint below mintcost(), or redeem below 1 wstGBP (1e18).
ExceedsCap()The mint would push totalSupply above capacity().
ClaimableAfter(uint256 time)exit(id) before the redemption’s claimable date.
NoPendingClaim()exit(id) on a settled or nonexistent redemption.
NotAuthorized(address usr)An address involved fails the cop ban-list screen, or an issuer-only call by a non-issuer.
TransferToContract()transfer / transferFrom with the token contract as destination.
TransferToZeroAddress()transfer / transferFrom to the zero address.
TransferFailed()The underlying tGBP transfer returned false.
PermitDeadlineExpired(uint256 deadline, uint256 actual)permit submitted after its deadline.
InvalidSigner(address recovered, address expected)permit signature does not recover to owner.
InvalidChain(uint256 expected, uint256 actual)permit domain guard after a chain split; not expected in practice.

ABI

A curated ABI covering mint/redeem/exit, the integrator views, and the three lifecycle events. Sufficient for viem/wagmi integration.

wstgbpAbi.ts
export const wstgbpAbi = [ { type: 'function', name: 'mint', stateMutability: 'nonpayable', inputs: [{ name: 'amt', type: 'uint256' }], outputs: [{ name: '_out', type: 'uint256' }] }, { type: 'function', name: 'redeem', stateMutability: 'nonpayable', inputs: [{ name: 'amt', type: 'uint256' }], outputs: [{ name: '_id', type: 'uint256' }] }, { type: 'function', name: 'exit', stateMutability: 'nonpayable', inputs: [{ name: 'id', type: 'uint256' }], outputs: [{ name: '_out', type: 'uint256' }] }, { type: 'function', name: 'navprice', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'mintcost', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'burncost', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'mintable', stateMutability: 'view', inputs: [], outputs: [{ type: 'bool' }] }, { type: 'function', name: 'burnable', stateMutability: 'view', inputs: [], outputs: [{ type: 'bool' }] }, { type: 'function', name: 'capacity', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'cooldown', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'totalSupply', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'balanceOf', stateMutability: 'view', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'gem', stateMutability: 'view', inputs: [], outputs: [{ type: 'address' }] }, { type: 'function', name: 'redemptionCount', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'canPass', stateMutability: 'view', inputs: [{ name: 'usr', type: 'address' }], outputs: [{ type: 'bool' }] }, { type: 'function', name: 'terms', stateMutability: 'view', inputs: [], outputs: [{ type: 'string' }] }, { type: 'function', name: 'nonces', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ type: 'uint256' }] }, { type: 'function', name: 'DOMAIN_SEPARATOR', stateMutability: 'view', inputs: [], outputs: [{ type: 'bytes32' }] }, { type: 'function', name: 'redemptions', stateMutability: 'view', inputs: [{ type: 'uint256' }], outputs: [ { name: 'amount', type: 'uint256' }, { name: 'redeemer', type: 'address' }, { name: 'date', type: 'uint96' }, ] }, { type: 'event', name: 'ContractCreated', anonymous: false, inputs: [ { name: 'creator', type: 'address', indexed: true }, { name: 'price', type: 'uint256', indexed: true }, { name: 'amount', type: 'uint256', indexed: true }, ] }, { type: 'event', name: 'ContractRedemption', anonymous: false, inputs: [ { name: 'id', type: 'uint256', indexed: true }, { name: 'date', type: 'uint256', indexed: true }, { name: 'redeemer', type: 'address', indexed: true }, { name: 'amount', type: 'uint256', indexed: false }, ] }, { type: 'event', name: 'ClaimProcessed', anonymous: false, inputs: [ { name: 'id', type: 'uint256', indexed: true }, { name: 'claimer', type: 'address', indexed: true }, { name: 'amount', type: 'uint256', indexed: true }, ] }, ] as const
Last updated on