Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SANDUIT

The SAN Loadout Locker - a UUPS-upgradeable commerce + orchestration contract for SAN Sound's Soundscape Avatars. It is the ownership-gated on-chain layer behind the SANSWAP/SANBOUND accessory system.

Deployed and upgraded on Ethereum mainnet; source verified on Etherscan. Solidity + Foundry.

What it does

SANDUIT is the economic layer: you acquire accessories (USDC-paid or free-claimed, via reusable EIP-712 grants) and either take them as tradeable SANSWAP in your wallet or bind them as soulbound SANBOUND into an avatar's ERC-6551 account - all gated by avatar ownership.

Wearing is not on-chain state. lockInLoadout is a pass-through that emits LoadoutLocked(...) so the sansound.tech backend can recomposite the avatar's art + metadata from the worn subset (checking on-chain that the avatar's TBA actually holds those accessories). Its value is bundling: a user already sending an acquire/bind transaction can commit their loadout in that same tx, sparing the separate off-chain signature they'd otherwise sign on the loadout-locker site.

Because acquire, bind, and the loadout emit compose freely, a single call can express any of the seven paths the contract documents - where every "wear"/"unwear" is carried by the emitted event, not tracked on-chain:

Path
1 Wear an already-bound accessory
2 Unwear one
3 Bind wallet SANSWAP + wear
4 Bind wallet SANSWAP (no wear)
5 Acquire → wallet (tradeable SANSWAP)
6 Acquire + bind + wear
7 Acquire + bind (no wear)

Technical highlights

  • UUPS-upgradeable with ERC-7201 namespaced storage - all mutable state lives in one SanduitStorage struct at a fixed, collision-resistant slot (keccak256("san.sanduit.storage") - 1 & ~0xff), read via inline assembly. Upgrade-safe by construction; deployed and then upgraded once in production behind a stable proxy.
  • EIP-712 grants as reusable allowances - a signed Claim(claimant, accessoryTokenId, maxAmount, deadline) is redeemable incrementally (claimedAmounts[digest] += amount, capped at maxAmount), so a grant is a spending limit, not a one-shot coupon. The signature deliberately omits the avatar id, so the grantee picks delivery at claim time: avatarId == 0 mints tradeable SANSWAP to their wallet; avatarId > 0 binds SANBOUND straight into that avatar's TBA.
  • USDC payment via EIP-2612 permit, hardened against griefing - the permit call is wrapped in try/catch, so an attacker front-running the permit can't brick the purchase; it falls back to the standing allowance. USDC address and 6-decimal pricing are chain-pinned.
  • Ownership-gated - every avatar-directed action checks avatars.ownerOf(avatarId) == msg.sender, closing the surface that raw SANSWAP intentionally leaves permissionless (for gifting).
  • Listing model - prices / caps / sold with a swap-and-pop listedTokenIds set; price == 0 && cap > 0 is a free-but-capped drop, while unlimited-free (price == 0 && cap == 0) is explicitly rejected.

Admin & roles

Operations run through OpenZeppelin AccessControl, so the loadout-locker admin portal can give each operator exactly the surface they need:

Role Can
DEFAULT_ADMIN_ROLE authorize UUPS upgrades, set the grant signer, administer roles
ACCESSORY_CREATOR_ROLE create and configure accessories (setupAccessories)
PRICE_MANAGER_ROLE set prices and supply caps
WITHDRAWER_ROLE withdraw ETH / USDC proceeds
PAUSER_ROLE pause / unpause
GRANTOR_ROLE not enforced on-chain; read by the admin portal to gate who may create/delete claim grants (the grants themselves are EIP-712-signed by the designated signer)

Deployed on Ethereum mainnet

SANDUIT lives at the ERC-1967 proxy 0x3310ad0117333f3b9d25857949df5a2e0856de3b (the canonical address). It was upgraded once via UUPS; the two implementation deployments are 0x2eea121f9f5f946cce573164205e389afa1bb7eb and 0x45cdb53b4ecf214709eb7d6f4feeb4369260eab7.

Depends on the SAN Sound avatar/accessory contracts in sanwear-contract (SANSWAP, SANBOUND, SoundscapeAvatars).

Build & test

Foundry; dependencies are git submodules (forge-std, OpenZeppelin, OpenZeppelin Upgradeable).

git clone --recursive https://github.com/coffee-converter/sanduit-contract
cd sanduit-contract
forge build
forge test

Credit & license

Authored by Aaron Hanson (principal engineer) for SAN Sound. MIT-licensed - see LICENSE.

About

A UUPS-upgradeable, EIP-712 commerce contract that binds Soundscape avatar accessories into ERC-6551 accounts, priced in USDC. Solidity and Foundry, verified on mainnet.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages