Developers

Contracts

The external surface of OpaquePool.

Copy Markdown

Draft

This is the draft interface. It may change before launch.

Structs

solidity
struct ExtData {
    address recipient;
    address caller;      // zero means anyone may submit
    uint256 fee;         // relayer fee, in shares
    bytes data;          // must be empty for now
    bytes ciphertext0;
    bytes ciphertext1;
}

struct Transaction {
    uint256 root;
    uint256[2] nullifiers;
    uint256[2] commitments;
    uint256 assetId;
    uint256 exitAmount;
    ExtData ext;
}

Functions

solidity
function shroud(uint256 stub, uint256 amount, bytes calldata ciphertext) external returns (uint32 index);
function transact(Transaction calldata t, bytes calldata proof) external;
function donate(uint256 amount) external;
function setDepositsPaused(bool paused) external;
FunctionDescription
shroudDeposits amount $OPA into a note completed with stub. Reverts while deposits are paused or above the cap
transactSpends up to two notes, creates two notes and optionally exits part of the value, paying the flat fee. Checks the root, the nullifiers and the proof
donateAdds $OPA to the vault backing without minting shares. Anyone can call it, also while deposits are paused
setDepositsPausedGuardian only. Pauses or resumes new shrouds. Nothing else

Views

solidity
function isKnownRoot(uint256 root) external view returns (bool);
function nullifierSpent(uint256 nullifier) external view returns (bool);
function depositCap() external view returns (uint256);
function sharesForTokens(uint256 amount) external view returns (uint256);
function tokensForShares(uint256 shares) external view returns (uint256);
function publicInputs(Transaction calldata t) external pure returns (bytes32[] memory);
function extDataHash(ExtData calldata e) external pure returns (uint256);

publicInputs and extDataHash are exposed so clients and tests build the same values the contract checks.

Events

solidity
event NoteAdded(uint256 indexed index, uint256 commitment, bytes ciphertext);
event NullifierSpent(uint256 indexed nullifier);
event Shrouded(address indexed from, uint256 indexed index, address indexed asset, uint256 amount, uint256 units);
event Exited(uint256 indexed nullifier, address indexed recipient, address indexed asset, uint256 amount);
event Donation(address indexed from, address indexed asset, uint256 amount);
event AssetRegistered(uint256 indexed assetId, address indexed asset, bool shareBased);

Wallets rebuild the tree and find their notes from NoteAdded.

Errors

ErrorRaised when
DepositsPausedA shroud while the guardian has paused deposits
NotGuardianSomeone else calls setDepositsPaused
UnknownAssetAn asset id other than 1
BadAmountA zero or oversized amount
NotInFieldA value at or above the field size
CapExceededA shroud above the current deposit cap
ZeroSharesA $OPA shroud that would mint no shares
UnknownRootA proof against a root that is not in the last 64
NullifierUsedA nullifier already spent
DuplicateNullifierBoth nullifiers in a transaction are the same
WrongCallerext.caller is set and the sender is someone else
FeeTooHighRelayer fee plus the flat fee exceeds the exit amount
BadExitAn exit without a recipient, or a fee with no exit
ExitTargetsNotSupportedext.data is not empty
InvalidProofThe verifier rejects the proof
TransferFailedA token transfer fails
EthNotAcceptedETH sent to the pool
FeeOnTransferTokenThe token delivered less than requested
InsufficientBackingAn exit larger than the pool holds
ReentrancyA reentrant call