Part 1: Smart Contracts
The entire booking system of Fiat24 is managed transparently on the Arbitrum and Mantle blockchain, both are leading Layer 2 rollup solution for Ethereum.
Tokens
Fiat24 users hold Fiat24 Cash Tokens — USD24, EUR24, CHF24, and CNH24 — which are ERC-20 tokens backed one-to-one by cash deposits. These tokens are issued by SR Saphirstein AG, a Swiss licensed deposit-taking institution. Customers can interact with their Fiat24 accounts either through the official Fiat24 dApp or via any compatible native crypto wallet.
0xbE00f3db78688d9704BCb4e0a827aea3a9Cc0D62 // USD24
0xd41F1f0cf89fD239ca4c1F8E8ADA46345c86b0a4 // CHF24
0x2c5d06f591D0d8cd43Ac232c2B654475a142c7DA // EUR24
0x7288Ac74d211735374A23707D1518DCbbc0144fd // CNH240xD598839598bBF508b97697b7D9e80054D4bcaaCC //USD24
0x0578be9C858e6562dd8cd11a738b89Ca48194dA5 //EUR24
0x53587A05ccDdCE555C2Cd7cE4C9c5Bc3D912E2f3 //CHF24
0xa0af0C397CB0A52F5E8Bc7BB89068dDDfaE9F211 //CNH24
0x3bC9fC0460cAC2DdD352848ECc0BFe204c220717 //JPY24
0x8F7F92F2A0247cc8660C4C4EF69582Bc6849B4d9 //SGD24
0x64266a15432004708e5fCA0239f664d069853374 //HKD24Fiat24 uses ERC721 based NFT to represent a Bank Account. If a user owns the NFT in their wallet, the wallet have the control to all Fiat24 services. The id of the NFT represents the account number of Fiat24.
0x133CAEecA096cA54889db71956c7f75862Ead7A00x4a05148119683E0A41b52fb973EEF0EE81536c47Functions
In this section, we introduce various types of smart contract interactions using JavaScript. The JS code shown below is implemented using ethers.js.
1. Mint an NFT
Minting a Fiat24 NFT for the user is the first step in the process. The wallet provider should generate a random number with at least five digits to serve as the user’s NFT ID. Before minting, the wallet provider must verify that the NFT ID has not already been taken; otherwise, the transaction will fail with an error. A successful minting typically costs around 0.01 USD in gas fees.
We have 2 ways to mint the NFT:
End user mints the NFT
Wallet users call the mintByClient() to mint the NFT. The NFT id is his/her Fiat24 account number, which maps to the unique Swiss IBAN account. The IBAN mapping logic refers here.
Wallet provider mints the NFT for the user
The wallet provider may choose this approach to gain two key benefits:
The ability to issue customized debit cards to users.
The ability to receive 1% referral fees (in USDC) from each crypto conversion transaction.
To implement this approach, each wallet provider must have:
A Fiat24 developer NFT — an NFT ID in range 8000 to 8999. This NFT will be registered as the wallet provider account.
A certain amount of F24 tokens to burn, which is the ERC-20 utility token of the Fiat24 ecosystem.
Therefore, an ERC-20 approve transaction is required from the wallet provider’s address to the Fiat24Account contract. This means the wallet provider NFT holder must hold a sufficient balance of F24 tokens in their account.
The mintByWallet() function mints the client NFT and sets the wallet provider ID in the Fiat24Account NFT.
By end of 2024, all 5 digits NFT were already minted by wallets, so only 6 digits are available.
Please only call mintByClient or mintByWallet function with a 6-digits NFT number, and starts with 1..7.
So the following number should NOT be mint:
2563, which is not a 5-digits-number
89052, which doesn't start with 1 to 7.
91023, which doesn't start with 1 to 7.
5623147, which is not a 6-digits-number
2. Upgrade NFT
The wallet provider can mint NFTs with five or more digits for standard clients, who have a restricted transaction volume.
To upgrade to a Premium client status — represented by an NFT with one to four digits — the user must spend F24 tokens to complete the upgrade. Typically, upgrading to a four-digit NFT requires burning 1,500 F24 tokens. The steps for this process are detailed in the script below:
Notice: The function upgradeWithF24(tokenId) is called by client's address, not from wallet provider's address.
3. Get Balances
Retrieve the user's multi-currency account balance accounts. It returns all balance accounts from the address which holds the client NFT.
All Fiat24 cash tokens have decimal of 2.
4. Get Account Status
The user should be informed by their account status from the NFT.
The status number is an integer between 1 and 5 and stands for:
Soft-Blocked, the user can receive money only, but can't send/spend anything.
Tourist status as unverified user
Hard-Blocked, the user can neither send nor receive any money.
Closed. Closed account.
Live. The user is fully verified as client.
5. Get limit
Each Fiat24 user will have an overall transactional limit for 30-days rolling basis. This limit value is given by Fiat24 internal risk function from our risk-based evaluation. A standard individual client with low risk profile will get 100,000 CHF (around 120,000 USD) limit for 30 days.
Partner can read this limit from NFT. Any transaction exceed this limit will throw an error from the smart contract calls.
6. P2P Payments
Standard ERC20 tokens allow users to transfer money to the recipient or beneficiary directly by an Arbitrum address
or by NFT id.
Notice that Solidity doesn't support decimals, so always use the integer to specify the amount. All Fiat24 cash tokens have 2 decimals, so user the money amount * 100 to represent the solidity amount. For example, if you want to transfer 122.45 USD24, then the parameter in the call will be 12245.
7. Cash Deposit
Cash Deposit booking are managed by Fiat24 internal. Once a user makes a bank deposit, a Cash Deposit booking will be credited from #9101 Cash In Desk.
To calculate the deposit account, please refer the /iban API.
8. Card Approval
The debit card payments are booked by the contract Fiat24CardAuthorization by the function authorize(). Therefore, the card owner (address) needs to approve a certain limit amount for future card spendings.
In Arbitrum, four currencies (USD24, EUR24, CHF24, CNH24) are supported for debit card. The card authorisation address is 0xe2e3B88B9893e18D0867c08f9cA93f8aB5935b14
In Mantle, more Asian currencies (HKD24, SGD24, JPY24) are supported as well. The card authorisation address is 0xb9d38DDE25f67D57af5b91C254F869F90d483d05
Once the approved amount is used, the approval needs to be repeated.
9. Cash Payout
Cash Payout is a cash withdrawal transaction to move client's money from Fiat24 account to one of his/her associated bank accounts.
The following code shows how to withdraw 100.55 CHF to user's registered bank account, which has the id of EA-0000001, which can be retrieved from Get Client Profile
NOTE: there is a minimum amount for the payouts, currently the value is set to 10 EUR /CHF. But the value can be found in the minimalPayoutAmount method in the smart contract.
Special payouts to selected platforms
For most regulated trading platforms, such as Securities Borker or Crypto Exchanges, normally the cash in operation must be from the account with the same account holder, together with a Reference, which is given by the platform.
The special method clientPayoutRef() can send EUR or CHF with such reference to specific platforms.
Here is the sample code:
Fiat24 maintains the list of whitelisted platforms, for the value of contactId above.
Here are some samples of these type of accounts, which some might be outdated, for getting the up to date account please fetch them in the RESTful API GET /br, using the whitelistedContacts field.
EUR Payouts (sample)
EA-00000739
Payward Ltd.
Kraken
EA-00000740
UAB Bifinity
Binance
EA-00000741
CB Payments, Ltd
Coinbase
EA-00000742
Bitstamp Europe S.A.
Bitstamp
EA-00000743
Tiger Brokers Singapore Pte Ltd
Tiger Securities
CHF Payouts (sample)
EA-00000738
Payward Trading Ltd.
Kraken
EA-00000759
Casino Zürichsee AG
Casino Zürichsee
10. Crypto Top-up
This function is the main integration point between wallets and Fiat24, it converts the cryptocurrency from the wallet into our fiat holdings, which are in the form of ERC20 tokens (USD24, CHF24 and EUR24) in the Arbitrum network.
We return 100% of the commission to the wallet provider. The commission is transferred as USDC (https://arbiscan.io/token/0xaf88d065e77c8cC2239327C5EDb3A432268e5831) to the address of the wallet provider, the same address which is used to call mintByWallet(). The commission is paid by each single top-up transaction, so there won't be any settlement or reconciliation effort for the wallet provider.
The commission is currently set to 1.0% of the top-up volume, as published in the Pricing page.
The commission is currently set to 0% of the top-up volume.
Swap Ether into Fiat24 Cash Token
Swap ERC20 into Fiat24 Cash Token, through ERC20/USDC or ERC20/ETH Uniswap V3 Pool
Swap USDC into Fiat24 Cash Token by Wallet Provider
For certain wallet providers, there is a common requirement to convert assets not present on Arbitrum into Fiat24 cash tokens, which can be achieved in two steps.
In the first step, the wallet initiates a cross-chain swap to convert any token (such as Bitcoin or Solana) into USDC on Arbitrum, depositing it into the end-user's address.
The second step involves the wallet provider initiating a smart contract call to convert the USDC into a Fiat24 token like EUR24. This action is performed by the wallet provider, requiring no user intervention for the top-up. Thus, from the user's perspective, the entire swap process appears seamless and is effectively completed in a single step.
Here is the smart contract function being called by wallet side:
End-User Side: The code provided below is on the end user's side to authorise the contract, allowing it to proceed with USDC the next step.
Wallet Side: The following code will be executed by wallet provider's side.
The message sender (or caller) must hold the wallet provider's NFT.
11. Money Exchange
Within their Fiat24 account, users can exchange between the available currencies — CHF, EUR, CNH and USD.
You can perform an exchange in either of the following cases:
• When you know the amount to sell For example, exchange 100.0 USD to EUR. In this case, specify the input amount as 100 USD.
• When you know the amount to buy For example, exchange USD to receive 100.0 EUR. In this case, specify the output amount as 100 EUR.
To complete the transfer, follow these two steps:
Get the exchange rate
Use the getExchangeRate() function to obtain a quote for the exchange rate.
Generating the quote requires providing the contract addresses of both the input and output currency tokens. The function returns the client rate, which includes a spread calculated based on the interbank market rate.
Execute the transaction
Method 1: You know the amount of currency to sell with moneyExchangeExactIn
Method 2: You know the amount of currency to buy with moneyExchangeExactOut
Done
Appendix: Code Example:
Last updated