Skip to content
Protocol contracts not yet configured for this build
Enter app

Architecture

PloutoRegistry

The registry is the protocol's address book and the single source of truth for whether PLOUTO exists. It is Ownable2Step, deliberately small, and mostly a set of one-way doors.

Immutable Pons wiring

Fixed at construction and never changeable:

solidity
address public immutable ponsFactory;address public immutable ponsFeeEscrow;address public immutable expectedLauncher;

The constructor requires bytecode at the factory and the escrow. expectedLauncher is the address expected to have executed the launch, and it is what prevents an attacker registering their own Pons launch.

Wiring the protocol

solidity
function wireProtocol(address revenueRouter_, address gravityStaking_, address buybackExecutor_, address reserve_)    external onlyOwner

Callable exactly once — a second call reverts with AlreadyWired(). Every address must be non-zero and have bytecode. This exists as a separate step because the four contracts are deployed after the registry.

The one-way door

solidity
function setPloutoTokenOnce(address token, address curve) external onlyOwner

This is the most consequential function in the protocol. It validates against the live Pons factory record, not against the caller's claims:

Basic checks

Not already initialized. Protocol wired. Both addresses non-zero and carrying bytecode.

Factory record

record.exists; record.token == token; record.curve == curve; record.deployer == expectedLauncher; record.creatorFeeRecipient == revenueRouter; record.pairToken == address(0).

Curve cross-check

The curve's own token(), pairToken() and factory() must agree. A spoofed factory record alone is not enough.

Supply

totalSupply() must be non-zero, read by staticcall so a non-conforming token reverts rather than silently passing.

Each failure has its own error: LaunchNotFound, TokenMismatch, CurveMismatch, UnexpectedLauncher, FeeRecipientMismatch, NotNativeQuote, ZeroSupply, NoCode, AlreadyInitialized, NotWired.

The initialization gate

solidity
function initialized() public view returns (bool) {    return ploutoToken != address(0);}

Everything downstream reads this. GravityStaking.stake reverts with NotInitialized if the token is unset; PloutoRevenueRouter.routeUnallocatedRevenue does the same; the frontend gates every control on it.

Events

solidity
event ProtocolWired(address revenueRouter, address gravityStaking, address buybackExecutor, address reserve);event PloutoInitialized(    address indexed token, address indexed curve, address indexed creatorFeeRecipient,    address launchDeployer, address pairToken, uint256 totalSupply, uint256 blockNumber);

PloutoInitialized fires once, ever. It is the canonical on-chain record of the launch.

What the registry cannot do

  • Hold or move value. It has no receive(), no token balance and no transfer function.
  • Change the token after initialization.
  • Grant itself permissions over the other contracts.
  • Be re-wired.

Ownership uses Ownable2Step, so a transfer requires the new owner to accept — a mistyped address cannot orphan the contract.