Skip to content

Smart Contracts (Reference)

The primary on-chain entry point for Twin.fun is the DigitalTwinSharesV1 contract.

Traits & Mixins

  • Ownable
  • AccessControl
  • ReentrancyGuard

Storage Layout

  • sharesBalance[id][address] → uint256
  • sharesSupply[id] → uint256
  • digitalTwinIdToOwner[id] → address
  • digitalTwinUrl[id] → string
  • digitalTwinExists[id] → bool
  • totalDigitalTwins → uint256

Configurable Parameters

  • protocolFeeDestination → address
  • protocolFeePercent → uint256 (1e18 = 100%)
  • subjectFeePercent → uint256 (1e18 = 100%)
  • minSharesToCreate → uint256

Owner-Only Setters

  • setFeeDestination(address)
  • setProtocolFeePercent(uint256)
  • setSubjectFeePercent(uint256)
  • setMinSharesToCreate(uint256)

Roles

  • DEFAULT_ADMIN_ROLE — deploy-time admin with full control.
  • CLAIM_OWNERSHIP_ROLE — can call claimOwnership(id, newOwner) to pre-map twin owners.

Events

  • Trade(trader, id, isBuy, shareAmount, ethAmount, protocolEthAmount, subjectEthAmount, supply)
  • DigitalTwinUrlSet(id, url)
  • DigitalTwinOwnershipClaimed(id, newOwner)

Read Functions

  • getPrice(uint256 supply, uint256 amount)
  • getBuyPrice(bytes16 id, uint256 amount)
  • getSellPrice(bytes16 id, uint256 amount)
  • getBuyPriceAfterFee(bytes16 id, uint256 amount)
  • getSellPriceAfterFee(bytes16 id, uint256 amount)

Write Functions

  • setDigitalTwinUrl(bytes16 id, string url) — twin owner only.
  • createDigitalTwin(bytes16 id, string url) — payable helper to set the URL and seed minimum liquidity.
  • buyShares(bytes16 id, uint256 amount) — payable, nonReentrant.
  • sellShares(bytes16 id, uint256 amount)nonReentrant.

Security Notes

  • nonReentrant guards on buy and sell.
  • ETH payouts use direct calls to the recipient address.
  • Fee percentages are owner-settable (no on-chain caps); integrate with appropriate warnings in UI.

OpenGradient 2025