Skip to content

EVM Contracts (Base L2)

SUDIGITAL's EVM deployment targets Base L2 as the primary chain, with planned expansion to Polygon, Ethereum, and Arbitrum. The codebase includes 8 contracts, 8 shared libraries, and 6 interfaces.

Deployed Contracts

ContractAddressStatus
SUDIGITAL Token0x4E13A52764aFC8AE4C23C58e67fDe8bf5F6C100bVerified, Mainnet
Gnosis Safe0xb0599ce3595Ed3768B08B9B4e7d96AF309a7f49a6-of-7, Active

Deployed: January 25, 2026 | Chain ID: 8453

Supported Chains

ChainChain IDTypeStatus
Base8453MainnetPrimary
Ethereum1MainnetPlanned
Arbitrum42161MainnetPlanned
Optimism10MainnetPlanned
Polygon137MainnetPlanned
Sepolia11155111TestnetAvailable
Base Sepolia84532TestnetAvailable

Contract Modules

All contracts use the UUPS proxy pattern (OpenZeppelin Upgradeable) with Solidity ^0.8.28.

SudigitalToken

ERC-20 token with admin controls for the launch period.

Inheritance: Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable, OwnableUpgradeable, UUPSUpgradeable

ConstantValue
TOTAL_SUPPLY1_000_000_000 * 10**6 (1B tokens, 6 decimals)
Token Name"Super Digital"
Token Symbol"SUDIGITAL"
Decimals6
FunctionAccessDescription
initialize(owner, treasury)AUTHORIZED_DEPLOYER onlyMints total supply to treasury
decimals()ViewReturns 6
pause() / unpause()OwnerEmergency circuit breaker
freezeAccount(account)OwnerFreeze individual account transfers
unfreezeAccount(account)OwnerUnfreeze account
isFrozen(account)ViewCheck frozen status
burn(amount)Any holderBurn own tokens (inherited)
burnFrom(account, amount)Any (with allowance)Burn with allowance (inherited)

Events: AccountFrozen(address indexed), AccountUnfrozen(address indexed)

AUTHORIZED_DEPLOYER is immutable, set in constructor, prevents re-initialization. Frozen account check enforced on all transfers via _update() override.

CoreModule (v0.6.6)

Platform configuration, user management, and claim proof processing.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable

FunctionAccessDescription
initialize(admin, emergencyContact)DeployerInitial setup
initializePlatformConfig(backendAuthority)OwnerSet trusted backend signer
updateBackendAuthority(newAuthority)OwnerRotate signing key
setPlatformActive(isActive)OwnerKill switch
updateAdmin(newAdmin)OwnerChange admin address
setEmergencyContact(contact)OwnerUpdate emergency contact
pause() / unpause()Owner or AdminEmergency pause
registerUser()AnyCreate UserProfile on-chain
processClaim(proof)AnyVerify claim proof (event-only, no routing)
getUserProfile(user)ViewGet full user profile
hasRole(user, role)ViewCheck role via bit flags
getUserLevel(user)ViewGet XP level
getUserXp(user)ViewGet total XP
meetsMissionRequirements(user, role, level)ViewCheck mission eligibility
getUserClaimState(user)ViewGet nonce/claim count
isValidNonce(user, nonce)ViewCheck nonce validity
getBackendAuthority()ViewGet trusted signer address
isPlatformActive()ViewCheck platform status

Rate Limits (enforced per-user per-day):

LimitValue
Max missions created per day100
Max mission joins per day500
Min creation interval60 seconds

StakingModule (v0.6.6)

Token staking with APY rewards and emission controls.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable, ReentrancyGuard

ConstantValue
LOCK_30_DAYS30 days
LOCK_90_DAYS90 days
LOCK_180_DAYS180 days
LOCK_365_DAYS365 days
APY_FLEXIBLE500 (5%)
APY_30_DAYS500 (5%)
APY_90_DAYS800 (8%)
APY_180_DAYS1000 (10%)
APY_365_DAYS1500 (15%, disabled Phase 1)
DEFAULT_MAX_STAKE_PER_WALLET100_000_000_000 (100K tokens)
DEFAULT_ANNUAL_EMISSION_CAP10_000_000_000_000 (10M tokens)
DEFAULT_MAX_LOCK_DURATION180 days
MIN_STAKE_AMOUNT1_000_000 (1 token)
MIN_HOLDERS_FOR_STAKING1111
MIN_TVL_FOR_STAKING_USD111,111
FunctionAccessDescription
stake(amount, lockDuration)AnyStake tokens with lock
unstake(amount)StakerWithdraw after lock expires
claimRewards()StakerClaim accumulated rewards
getApyForLockDuration(duration)ViewGet APY tier (caps at maxLockDuration)
calculateDailyRate(apyBps)PureapyBps / 365
getPendingRewards(user)ViewUnclaimed rewards
getStakeInfo(user)ViewstakedAmount, lockedUntil, pendingRewards, apyBps
getRemainingAnnualEmission()ViewRemaining emission capacity
updateStakingConfig(enabled, cap, maxStake, maxLock)OwnerFull config update
enableStaking() / disableStaking()OwnerConvenience toggles
fundRewardsPool(amount)OwnerAdd tokens to rewards pool
getRewardsPoolBalance()Viewcontract balance - totalStaked
getStakingConfig()ViewAll config values

Reward formula: rewards = staked * rewardRate * timeElapsed / (BASIS_POINTS * 1 days) -- second-based for precision.

Custom Errors: StillLocked, InsufficientStaked, NoRewardsToClaim, BelowMinimumStake, StakingDisabled, ExceedsMaxStakePerWallet, ExceedsAnnualEmissionCap, LockDurationExceedsMax

VestingModule (v0.6.6)

Team and advisor token vesting with linear release.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable, ReentrancyGuard

ConstantValue
CLIFF_DURATION365 days (12 months)
VESTING_DURATION1460 days (48 months)
MIN_VESTING_AMOUNT1_000_000 (1 token)
FunctionAccessDescription
createVesting(beneficiary, amount, start, cliff, duration)OwnerCreate schedule (uses defaults if 0)
releaseVested()BeneficiaryClaim vested tokens
revokeVesting(beneficiary)OwnerRevoke unvested tokens
withdrawUnlocked(amount, recipient)OwnerWithdraw tokens not locked in vesting
getReleasableAmount(beneficiary)ViewClaimable now
getVestedAmount(beneficiary)ViewTotal vested so far
getVestingInfo(beneficiary)ViewFull schedule details
getBeneficiariesCount()ViewNumber of vesting schedules

Custom Errors: VestingAlreadyExists, VestingNotFound, CliffNotReached, NoTokensToRelease, VestingAlreadyRevoked, InvalidAmount, InvalidDuration, InsufficientBalance, ZeroAddress

MissionModule (v0.6.6)

Mission escrow, winner recording, and reward distribution with rate limiting and circuit breaker.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable, ReentrancyGuard

FunctionAccessDescription
depositEscrow(missionId, paymentToken, amount, expiresAt)Any (payable)Fund mission escrow (ETH or ERC-20)
recordWinner(proof)BackendRecord verified winner, awards XP (75+500)
batchRecordWinners(proofs[])BackendBatch record (max 100)
claimReward(missionId)WinnerClaim with 80/15/5 split
refundEscrow(missionId)Creator/AdminRefund if cancelled/expired
setHolderShares(missionId, holders[], shares[])OwnerSet NFT holder reward shares
batchSetHolderShares(missionId, holders[], shares[])OwnerBatch set (max 100)
claimHolderReward(missionId)HolderClaim proportional holder reward
markRefundable(missionId)OwnerAllow refund on escrow
withdrawPending()AnyPull-payment fallback for failed ETH
setEconomyModule(address)OwnerSet economy module for XP awards
setEcosystemFund(address)OwnerSet ecosystem fund recipient
setDepositRateLimit(...)OwnerConfigure deposit rate limits
setClaimRateLimit(...)OwnerConfigure claim rate limits
resetCircuitBreaker()OwnerManual circuit breaker reset

Reward Distribution (enforced in claimReward):

PoolBPS%
Winner8,00080%
Holder Pool1,50015%
Ecosystem Fund5005%

Rate Limits:

ActionMax/HourMax/DayCooldown
Deposit105010s
Claim201005s

Supports both ETH and ERC-20 payments -- pass address(0) as paymentToken for native ETH.

NftModule (v1.2.0)

ERC-1155 NFTs with fractional ownership and SUDIGITAL token payment.

Inheritance: ERC1155Upgradeable, UUPSUpgradeable, OwnableUpgradeable, ReentrancyGuard (no PausableUpgradeable -- checks coreModule.isPlatformActive() instead)

ConstantValue
MAX_EDITION6,666
BASIS_POINTS10,000
FOUNDER_SHARE_BPS100 (1%)
CREATOR_SHARE_BPS100 (1%)
PLATFORM_SHARE_BPS9,800 (98%)
BURN_SHARE_OF_PLATFORM_BPS2,500 (25% of platform = ~24.5% total)
FunctionAccessDescription
mintNft(proof, maxShares)Any (with proof)Mint NFT with SUDIGITAL token payment
validateNftHolder(nftId, holder, minShares)ViewCheck holder status
migrateHolderShares(nftId, holders[])OwnerMigrate share data to ERC-1155
updatePlatformWallet(address)OwnerUpdate platform wallet
updateCreatorWallet(address)OwnerUpdate creator wallet
setURI(newuri)OwnerUpdate metadata URI
uri(tokenId)ViewMetadata URI with {id} replaced
getNftMetadata(nftId)ViewFull metadata
getHolderShare(nftId, holder)ViewShare info
canMintShare(nftId)ViewCheck availability
remainingShares(nftId)ViewShares left
getTotalBurned()ViewCumulative burn amount

Token IDs: Edition number directly (1-6666). The getTokenId(role, nftId) function ignores the role parameter and returns uint256(nftId).

First mint: 25% of price burned, 75% to platform. Creates NftMetadata with founder set. Subsequent mint: 1% founder + 1% creator + ~73.5% platform + ~24.5% burned. Payment: SUDIGITAL ERC-20 token only.

EconomyModule (v0.6.6)

XP system, leveling, and daily check-ins.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable

FunctionAccessDescription
initializeXp(user)Owner or AuthorizedCreate XP account
awardXp(user, baseXp)Owner or AuthorizedAward XP (auto-inits if needed)
checkIn()AnyDaily check-in (20 XP + streak bonuses)
updateMissionStats(user, completed, won, rewardAmount)Owner or AuthorizedUpdate mission counters
setAuthorizedCaller(caller, authorized)OwnerAuthorize contracts to call
getXpAccount(user)ViewFull XP data
getUserLevel(user)ViewCurrent level
getUserXp(user)ViewTotal XP
getUserStreak(user)ViewConsecutive login days
getXpThreshold(level)PureXP needed for level
getLevelName(level)PureLevel name string
getLevelMultiplier(level)PureMultiplier in BPS

Check-in rewards: 20 XP base, 150 XP at 7-day streak, 1,000 XP at 30-day streak. Streak: 1-day window + 1-hour grace period. Breaks if >25 hours since last login. Storage gap: 48 slots (other modules use 50).

AirdropModule (v1.0.0)

Pull-based airdrop distribution with custom reentrancy guard.

Inheritance: UUPSUpgradeable, OwnableUpgradeable, PausableUpgradeable (custom reentrancy, NOT OZ ReentrancyGuard)

FunctionAccessDescription
createAirdropEscrow(tokenAddress, amount)OwnerCreate and fund escrow
refillEscrow(airdropId, amount)OwnerAdd more tokens
claimAirdrop(proof)Any (with proof)Claim airdrop with signed proof
deactivateAirdrop(airdropId)OwnerPause airdrop
activateAirdrop(airdropId)OwnerResume airdrop
closeAirdropEscrow(airdropId)OwnerClose and return remaining
setBackendAuthority(newAuthority)OwnerUpdate signer

Shared Library Details

Roles.sol

enum Role {
    None,      // 0
    Memer,     // 1
    Worker,    // 2
    Player,    // 3
    Trader,    // 4
    Builder,   // 5
    Owner,     // 6
    Admin      // 7
}

Roles use bit flags for efficient multi-role storage: toBitFlag(role) returns 1 << (uint8(role) - 1).

TokenAllocation.sol (6 decimals)

AllocationBPSTokens
Ecosystem4,000 (40%)400_000_000 * 10**6
Treasury2,500 (25%)250_000_000 * 10**6
Team1,500 (15%)150_000_000 * 10**6
Sale1,000 (10%)100_000_000 * 10**6
Liquidity1,500 (15%)150_000_000 * 10**6

Also defines: MAX_STAKE_PER_WALLET, ANNUAL_EMISSION_CAP, DAILY_EMISSION_CAP, MAX_LOCK_DURATION_PHASE1.

MissionTypes.sol

EnumValues
MissionStatusCreated(0), Active(1), Completed(2), Cancelled(3), Failed(4), Expired(5)
MissionTypeTask(0), Challenge(1), Quiz(2), Tournament(3), Prediction(4), Social(5)
MissionDifficultyBeginner(0), Intermediate(1), Advanced(2), Expert(3), Master(4)

Error Codes

All errors are string constants in Errors.sol (e.g., string public constant UNAUTHORIZED = "6110"). Key ranges:

RangeModuleExample Codes
6100-6199Core6110 Unauthorized, 6120 ProofExpired, 6130 PlatformNotActive
6200-6299Economy6211 InvalidXpAmount, 6230 AlreadyCheckedInToday
6300-6499NFT6312 MaxSharesReached, 6331 InsufficientPayment
6500-6799Mission6500 EscrowNotActive, 6560 CircuitBreakerOpen
6800-6899Token6810 SupplyExceeded, 6840 TokenPaused
7000-7099Staking7004 StakingDisabled, 7005 ExceedsMaxStake
7200-7299Vesting7201 CliffNotPassed, 7202 VestingRevoked
7300-7399Roles7301 RoleAlreadyOwned, 7305 MaxNftsReached
7400-7499Security7401 RateLimitHourly, 7410 CircuitBreaker

One backend. Three products. One token.