> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arcpass.vibepas.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ArcPass Smart Contracts on the Arc Network Testnet

> Explore the on-chain contracts that back ArcPass sponsorships, how to verify your sponsorship status directly on Arc testnet, and key events to watch.

ArcPass relies on two Solidity contracts deployed on Arc testnet (chain ID `5042002`) to handle the treasury and the permanent record of every sponsorship. These contracts are the source of truth for sponsorship activity — every transfer and every record can be verified on-chain, independently of the ArcPass API.

<Note>
  The deployed contract addresses for SponsorVault and SponsorshipRegistry are shown on the ArcPass web interface home page.
</Note>

## SponsorVault

`SponsorVault` holds the native token treasury and is the only contract that can execute sponsorship transfers. When ArcPass processes an approved request, its relay worker calls `sponsorTransfer` on this contract to send tokens to your wallet.

### Key function: `sponsorTransfer`

```solidity theme={null}
function sponsorTransfer(address recipient, uint256 amount) external
```

This function transfers `amount` native tokens to `recipient`. Before executing the transfer, the contract verifies:

* The recipient has not been sponsored before (`sponsorshipCount == 0` on the registry)
* The requested amount does not exceed the per-transaction limit
* The vault holds sufficient balance

If any check fails, the transaction reverts. A successful call records the sponsorship in `SponsorshipRegistry` before transferring funds, ensuring the on-chain ledger is always consistent.

## SponsorshipRegistry

`SponsorshipRegistry` is an immutable on-chain ledger of all sponsorships. Only `SponsorVault` can write to it. You can read from it freely to verify whether any wallet has been sponsored.

### Key functions

```solidity theme={null}
// Returns true if the wallet has been sponsored at least once
function isSponsored(address wallet) external view returns (bool)

// Returns the total number of sponsorships recorded for the wallet
function sponsorshipCount(address wallet) external view returns (uint256)
```

For ArcPass's one-sponsorship-per-wallet model, a `sponsorshipCount` of `1` and `isSponsored` returning `true` both indicate the wallet has received its sponsorship.

### The `SponsorshipGranted` event

Every time a sponsorship is recorded, the registry emits:

```solidity theme={null}
event SponsorshipGranted(
    address indexed recipient,
    uint256 amount,
    uint256 timestamp
);
```

| Field       | Description                                           |
| ----------- | ----------------------------------------------------- |
| `recipient` | The wallet address that received the sponsorship      |
| `amount`    | The amount of native tokens transferred, in wei       |
| `timestamp` | The block timestamp when the sponsorship was recorded |

You can use this event to find the exact block and amount associated with any sponsorship by filtering on the `recipient` address.

## Verifying your sponsorship on-chain

You can check whether your wallet has been sponsored at any time by calling the read-only `isSponsored` function. No transaction or gas is required — this is a free view call.

<CodeGroup>
  ```javascript ethers.js theme={null}
  import { ethers } from 'ethers';

  const REGISTRY_ABI = [
    'function isSponsored(address wallet) view returns (bool)',
    'function sponsorshipCount(address wallet) view returns (uint256)',
  ];

  const provider = new ethers.JsonRpcProvider('https://rpc.arc-testnet.example');
  const registry = new ethers.Contract(REGISTRY_ADDRESS, REGISTRY_ABI, provider);

  const sponsored = await registry.isSponsored('0xYourWalletAddress');
  console.log('Sponsored:', sponsored); // true or false

  const count = await registry.sponsorshipCount('0xYourWalletAddress');
  console.log('Sponsorship count:', count.toString()); // "0" or "1"
  ```

  ```solidity Solidity theme={null}
  // SPDX-License-Identifier: MIT
  pragma solidity 0.8.20;

  interface ISponsorshipRegistry {
      function isSponsored(address wallet) external view returns (bool);
      function sponsorshipCount(address wallet) external view returns (uint256);
  }

  contract MyContract {
      ISponsorshipRegistry public registry;

      constructor(address registryAddress) {
          registry = ISponsorshipRegistry(registryAddress);
      }

      function checkSponsored(address wallet) external view returns (bool) {
          return registry.isSponsored(wallet);
      }
  }
  ```
</CodeGroup>

Replace `REGISTRY_ADDRESS` with the address shown on the ArcPass home page and `0xYourWalletAddress` with the wallet you want to check.

## Contract summary

<CardGroup cols={2}>
  <Card title="SponsorVault" icon="vault">
    Holds the native token treasury and executes sponsorship transfers. The relay worker is the only authorized caller of `sponsorTransfer`. Verifies eligibility on-chain before every transfer.
  </Card>

  <Card title="SponsorshipRegistry" icon="book">
    Permanent, immutable ledger of all sponsorships. Exposes `isSponsored()` and `sponsorshipCount()` for public verification. Emits `SponsorshipGranted` on every recorded sponsorship.
  </Card>
</CardGroup>
