In October of 2024 I attended Chainlink's 2-day bootcamp on tokenized real world assets. In this README I will explain how to complete the exercises of the bootcamp using Foundry, instead of Remix, which was the IDE employed during the online lessons. To follow this, make sure to take a look at the course's GitBook first!
The bootcamp was a 2-day program with a long exercise on the first day and two shorter ones on the second. All three are explained below.
On exercise 1, we created a fractional NFT representing a real estate property, leveraging the ERC-1155 standard. We also made it a cross-chain asset, leveraging Chainlink CCIP. The issuance of the token, which in a real use case would entail technical and legal complexities, was out of scope for this course. The steps to complete the exercise with the code in this repo are as follows:
-
We first deploy the
RealEstateToken(the contract for the tokenized property) and theIssuer(the contract that mocks the process of issuing the tokens, which has technical and regulatory complexities) contracts on Fuji by running:make deploy-fuji
This will also make a call to
RealEstateToken::setIssuer(), passing the address of theIssuercontract as a parameter. You can see the deployed contracts here and here.For some reason, verification on Snow Trace failed, so we decided to just make the necessary calls to these contract using cast.
-
Next, we create the subscription to Chainlink Functions, fund it with 10 LINK and add as consumers both contracts deployed in step 1.
-
Then, we call the
Issuer::issue()function to create 20 tokens (ERC1155 standard):cast send --rpc-url $FUJI_RPC_URL --private-key $PRIVATE_KEY 0x768b85F01D666150968c0dB9C0F6538F0D274B00 "issue(address,uint256,uint64,uint32,bytes32)" 0x31e0FacEa072EE621f22971DF5bAE3a1317E41A4 20 12946 300000 0x66756e2d6176616c616e6368652d66756a692d31000000000000000000000000
-
Next, we create a time-based upkeep on Chainlink Automations, which shall keep the price of the property updated in the smart contract by calling
RealEstateToken::updatePriceDetails()every day at 00:00 UTC. You can find here the first call the upkeep made to theupdatePriceDetailsfunction at 00:00 hours on the 2nd of Octobre of 2024. -
Once the upkeep is deployed, we call
RealEstateToken::setAutomationForwarder()passing the address of the upkeep's forwarder as a parameter, so that only the forwarder can call theRealEstateToken::updatePriceDetails()function. -
Finally, we deploy the
RealEstateTokencontract on Sepolia, so that the tokenized property can be transferred cross-chain:make deploy-sepolia
Note that this time the command will only deploy the
RealEstateTokencontract due to the chain sensitive conditions set up in the deployment script. This is because the issuer contract only needs to be deployed in the RealEstateToken's main chain, while the RealEstateToken contract itself has to exist on all the chains to which the token may be transferred. You can see the deployed contract here.
Note: Due to unusually high gas prices on Sepolia (see the screenshot below), deploying the contract there was not possible. The link will be updated whenever possible.
On the second exercise, the goal was to create a use case of how the tokenized real world asset could be used. In this first use case, a lending smart contract was created that allowed to take a loan of up to 60% of the tokens used as collateral. This way, just by owning a portion of the fractionally tokenized asset, money could be borrowed against it. If the value of those tokens (checked daily by the upkeep) fell below 75% of their original value, the collateral would be forfeited.
To deploy it, we created another deployment script and run the following command:
forge script script/DeployRwaLending.s.sol --rpc-url $FUJI_RPC_URL --private-key $PRIVATE_KEY --broadcast --verifier-url $SNOWTRACE_VERIFIER_URL --etherscan-api-key $SNOWTRACE_API_KEYThe contract was deployed to this address.
On the third exercise, we studied a second use case, an English auction. The idea was to make it possible for the owner of the Real Estate Tokens to sell them on auction. Check out the code in the repo or the GitBook linked above for more details.
This time we decided to deploy the contract without using a script, with the following command:
forge create src/use-cases/EnglishAuction.sol:EnglishAuction --rpc-url $FUJI_RPC_URL --private-key $PRIVATE_KEY --constructor-args 0xD070e42168928faDA13acBD708281c64D5087A39The contract was deployed to this address.
