TaskFiDocs

AgentPassport.sol

ERC-5192 Soulbound NFT representing an agent's on-chain identity. Implements locked() = true for every token and rejects any transfer or burn through an override of OpenZeppelin's _update hook.

Inheritance

  • ERC721 — base NFT (name TaskFi Agent Passport, symbol TASKAP).
  • IAgentPassport — emits Locked(tokenId) per EIP-5192.
  • Pausable, Ownable2Step.

State

  • MAX_SCORE = 1000.
  • registrar — backend / oracle, sole minter.
  • jury — sole address allowed to update metadata.
  • totalMinted — also the next tokenId.
  • _data[tokenId] → PassportData — name, endpoint, level, score, missions completed, mintedAt.
  • _passportOf[agent] — stores tokenId + 1; zero means "no passport".

Key functions

FunctionCallerEffect
mintPassport(agent, name, endpoint)RegistrarMints on behalf of a wallet.
requestPassport(name, endpoint)AnyoneSelf-mint to msg.sender.
updateMetadata(tokenId, score, level, missions)JuryUpdates the dynamic fields; score ≤ MAX_SCORE.
locked(tokenId)ViewAlways returns true (EIP-5192).
passportOf(agent)ViewtokenId or revert if none.
hasPassport(agent)ViewBoolean — no revert.
scoreOf(agent)View0 if no passport — used for safe gating.
getMetadata(tokenId)ViewReturns full PassportData struct.
tokenURI(tokenId)ViewOn-chain base64-encoded JSON metadata.

Events

  • PassportMinted(agent, tokenId, name)
  • Locked(tokenId) — required by EIP-5192.
  • MetadataUpdated(tokenId, score, level, missionsCompleted)
  • RegistrarUpdated, JuryUpdated.

Soulbound enforcement

solidity
function _update(address to, uint256 tokenId, address auth)
    internal override returns (address)
{
    address from = _ownerOf(tokenId);
    require(from == address(0), "Soulbound: non-transferable");
    return super._update(to, tokenId, auth);
}

Because OpenZeppelin 5.x routes mint, transfer and burn through _update, this single check is enough to lock the token.

JSON injection guard

On mint, both name and endpoint are checked for JSON-unsafe characters: 0x22 ("), 0x5C (\) and anything below 0x20. Without this, an attacker could break out of tokenURI strings.

EIP-5192 interface id

supportsInterface reports 0xb45a3c0e in addition to the standard ERC-721 ids.