Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.driftidentity.xyz/llms.txt

Use this file to discover all available pages before exploring further.

DriftID runs on two smart contracts deployed to Base mainnet. The first manages your identity and on-chain stats; the second governs the challenge arena where duels are staked, resolved, and recorded. Understanding how these contracts interact gives you everything you need to interact with the protocol directly or build applications on top of it.

Contract addresses

Both contracts are deployed to Base mainnet. You can verify them on Basescan or interact with them through any EVM-compatible tool.
ContractAddress
SkillDriftProfile0xCB0deD3D5DD9AE7B721272D5DBAB5d99CD5eeB6B
SkillDriftChallenge0x1caF2e8918202E202183e379EFE95D9777827A5B

SkillDriftProfile — the identity layer

SkillDriftProfile is your Drift ID on-chain. It stores your four primary stats (Focus, Discipline, Social, Risk), enforces the soulbound guarantee so your identity cannot be traded, and verifies Oracle-signed updates using EIP-712 typed data.
contract SkillDriftProfile is ERC721, EIP712, Nonces, Ownable

mintProfile()

One-time soulbound mint with a ~0.001 ETH fee. Each wallet can hold at most one Drift ID.

updateStatsWithSignature()

Accepts an Oracle-signed EIP-712 payload and applies verified stat progression to your profile.

updateStatsFromChallenge()

Called by the Challenge contract after a duel resolves. Records wins, losses, and stat changes.

getStats()

Public read function. Returns all four stat values for any profile ID.

Soulbound transfer prevention

Your Drift ID cannot be transferred to another wallet. The contract overrides the standard ERC-721 _update() hook and reverts any transfer between two non-zero addresses:
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
    address from = _ownerOf(tokenId);
    if (from != address(0) && to != address(0)) {
        revert ProfileNonTransferable();
    }
    return super._update(to, tokenId, auth);
}
Minting (from the zero address) and burning (to the zero address) are still permitted. Only wallet-to-wallet transfers are blocked.

Oracle authorization and EIP-712 verification

The contract stores a single authorizedSigner address. When you submit a stat update, the contract verifies that the accompanying signature was produced by that signer over a typed EIP-712 struct. Replay protection is handled by per-profile nonces — the same signed payload cannot be submitted twice.
The contract owner can rotate the authorizedSigner address at any time. If the Oracle key is ever compromised, key rotation prevents any further fraudulent updates without redeploying the contract.
The contract also includes an explicit signing key blacklist to prevent known compromised or testnet keys from ever being used to sign updates on mainnet.

SkillDriftChallenge — the arena layer

SkillDriftChallenge manages the full lifecycle of a duel: stake deposit, escrow hold, deterministic resolution, fee deduction, reward payout, and the callback to update stats in the Profile contract.
contract SkillDriftChallenge is Ownable, ReentrancyGuard

createChallenge()

Open a duel against another Drift ID. Your ETH stake is held in escrow until the duel resolves or is cancelled.

acceptChallenge()

Match the challenger’s stake and trigger automatic resolution. The outcome is determined using block.prevrandao.

cancelChallenge()

Reclaim your stake if the challenge has not been accepted yet. No penalty applies.

withdrawFees()

Owner-only function that moves accumulated Drift Tax from the contract to the treasury.

Resolution and the Drift Tax

When acceptChallenge() is called, the contract resolves the duel deterministically using block.prevrandao sourced from the Base L1 beacon chain. The winner receives 97.5% of the combined pot; the remaining 2.5% (the Drift Tax) accumulates in the contract until withdrawn to the treasury. All ETH-transferring functions are protected by OpenZeppelin’s ReentrancyGuard, preventing reentrancy attacks during payouts.
If you are building a front end or bot that interacts with the Challenge contract, listen for the challenge creation events to track open duels without polling contract state.