Skip to main content

Smart Contracts Overview

AceSteps is powered by four core smart contracts deployed on Base Network.

Contract Architecture

┌─────────────────────────────────────────────────────────────┐
│ USER │
└─────────────────────────────────────────────────────────────┘
│ │
│ mint(signature) │ enableTrading()
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ SongNFT │───────▶│ SongVault │
│ (ERC-721) │ │ (Permanent Lock) │
│ │ │ │
│ • Signature verify │ │ • Lock NFT │
│ • Metadata storage │ │ • Deploy token │
│ • Publish status │ │ • Create pool │
└─────────────────────┘ └─────────────────────┘

│ deploys

┌─────────────────────┐
│ SongToken │
│ (ERC-20) │
│ │
│ • 100,000 supply │
│ • 18 decimals │
│ • Fixed, no mint │
└─────────────────────┘

│ creates pool

┌─────────────────────────────────────────────────────────────┐
│ UNISWAP V4 │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ PoolManager │◀──────▶│ RevenueHook │ │
│ │ │ │ │ │
│ │ • SONG/ETH pools │ │ • donate() revenue │ │
│ │ • 1% swap fee │ │ • afterSwap events │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Contract Summary

ContractStandardPurposeKey Functions
SongNFTERC-721Song ownershipmint(), publish()
SongVaultCustomNFT locking, token deploymentenableTrading()
SongTokenERC-20Fractional ownershipStandard ERC-20
RevenueHookUniswap V4Revenue distributiondonate(), afterSwap()

Network Details

PropertyValue
NetworkBase (Ethereum L2)
Chain ID8453 (mainnet), 84532 (sepolia)
DEXUniswap V4
FrameworkFoundry

Security Features

Signature-Based Minting

Only AI-generated music can be minted:

// Backend signs: hash(userAddress + metadataURI + audioHash)
// Contract verifies via ECDSA.recover()
require(ECDSA.recover(hash, signature) == platformSigner);

Replay Attack Prevention

mapping(bytes => bool) public usedSignatures;

require(!usedSignatures[signature], "Signature already used");
usedSignatures[signature] = true;

Permanent Locking

NFTs cannot be unlocked once trading is enabled:

  • No unlock() function exists
  • 100% token buyback is mathematically impossible (AMM curve)
  • Prevents rug pulls

Access Control

modifier onlyPlatform() {
require(msg.sender == platformAddress, "Not authorized");
_;
}

Emergency Controls

function pause() external onlyOwner {
_pause();
}

Token Parameters

ParameterValue
Token StandardERC-20
Fixed Supply100,000 tokens per song
Decimals18
Creator Allocation80% (80,000 tokens)
LP Allocation20% (20,000 tokens)

Uniswap V4 Pool Parameters

ParameterValue
Token PairSONG_TOKEN / ETH (native)
Fee Tier1% (10000 bps)
Tick Spacing60
Initial LiquiditySingle-sided (0 ETH + 20,000 TOKEN)
HookSongRevenueHook

Development

Local Setup

cd blockchain
forge install
forge build
forge test

Deployment

forge script script/Deploy.s.sol:DeployScript \
--rpc-url $BASE_RPC_URL \
--broadcast \
--verify

Vault Mapping Structure

Bidirectional mappings for metadata access:

MappingUsage
lockedNFTs[nftId] → tokenAddressFind token from NFT
tokenToNFT[tokenAddress] → nftIdFind NFT from token