Inspiration
I walked by a building and asking myself these questions: How can a small investor owns a bit of real estate with only a few hundreds dollars? How can we cut out the middle men at REIT? How can we leverage the "idle" cryptocurrency portfolio?
The most popular option now is staking, I think we can provide an alternative, put your crypto in projects backed by real estate.
What it does
The app lets small investors to invest in a real property. This is how we can leverage their idling cryptocurrencies. We tokenize (ERC20) the real property and investors can buy the tokens to co-own the property, there is an "operator" (sort of like a lead investor) who will take care of the legal payment work like mortgage, tenants...etc. But the sale and monthly distributed dividend (monthly rent) are taken care by 3 smart contracts on the blockchain to provide cryptographically guarantee.
If an investor wants to sell his tokens, he can also run an English-style auction on our platform as well. This will provide liquidity and quick-
How we built it
We started with the business logic and turned those logic into 3 smart contracts. RptToken contract governs the ERC20 token (capped at 350, $5 each), which we built from scratch because we wanted to embed the dividend-bearing feature. Then the TokenSale contract governs how the sale of the tokens should be executed (with 1.5% fee paid to the operator). Eventually, the Auction contract governs how investors can sell their tokens safely.
Challenges we ran into
- We can only end-to-end test on Rinkeby As we use Chainlink ETH/USD live data feed, which governs how ETH and USD is converted, it has to be on live testnet (hardhat local environment doesn't work). This ETH/USD rate is used in all of our important function such as selling tokens, auction tokens...etc.
In addition, reality real estate price is huge, so we have to scale back all numbers (down-payment needs to be raised, monthly rent...etc.) to demo our functions. We don't have enough testing ETH to conduct all the tests.
Floating point number with Solidity & & Big Number problems with JavaScript In reality, real estate price is quoted in USD and we want our tokens to be quoted in USD. Then, investor will pay for it with ETH. Solidity doesn't support decimal numbers like $5.75 or $800.35. We can't just input these numbers directly into our smart contracts. Because all transactions on Ethereum blockchain must be executed with Wei (1 ether = 10^18 wei), we also faced the BigNumber problem as 18-digit numbers fall out of "safe range of value" of JavaScript. Making sure the convert rate is accurate all the time and figure out the right format of all numbers both on the back-end (smart contracts) and the front-end (web browser) is a huge challenge.
Accurate and Safe Dividend Distribution (monthly rent) Tokenholders are proportionally entitled to monthly dividend generated by the rental property. It is infeasible and extremely costly to code a loop function in which we get into every single account and distribute dividend every month. On the security standpoint, we should not actively send money to users as it poses a lot of risks such as re-entrancy risk and the fallback function (on the other end) can be malicious. In addition, we have to address the double-claim problem: that means after receiving the dividend, a bad actor can transfer his tokens to another account and claim the dividend again
Timestamp problem on running auction. Upon researching the timestamp attack, in reality, we realized that miners can manipulate timestamp of a block. Thus, a better solution is to use block.number instead of block.timestamp.
Rinkeby Testnet: transactions are reverted! As we conducted all of our tests on the rinkeby testnet, transactions are reverted because of realistic reasons like: can't estimate gas, insufficient fund...etc.
Accomplishments that we're proud of
For the floating point number problem with Solidity.:
We figured out a way to compute a universal ETH/USD exchange rate that can be used to convert and verify all payments on our app. The key idea is to convert USD directly to Wei, instead of Ether. Internal decimal is 2 because we want to keep 2 decimals for the USD price quote ($125.25 will be presented by 12525 on our smart contract).
rateDecimals = 8, basicDecimals = 18, internalDecimals = 2
function usdToWeiRate() public view returns (uint256) {
( ,int256 usdToEth, , , ) = priceFeed.latestRoundData();
(uint8 rateDecimals) = priceFeed.decimals();
uint256 usdToWei = uint256(10**(rateDecimals + basicDecimals() - internalDecimals))/uint256(usdToEth);
return usdToWei;
we want to
}
For the BigNumber problem: We figured out the right way to manipulate different types of variable: string to number and vice versa. An example is like this:
const ethCalculation = async () => {
let exchangeRate1 = await contract.usdToWeiRate();
let ethAmountInWei = BigNumber.from(((inputs.numberOfTokens*500*1.02)*exchangeRate1).toString());
const ethAmount = ethers.utils.formatUnits(ethAmountInWei, 18);
setEthAmount(ethAmount);
}
const buyRPT = async () => {
await contract.buyRPT(defaultAccount, inputs.numberOfTokens, { value: ethers.utils.parseUnits(ethAmount).toString() });
For the safe and accurate dividend distribution:
Instead of actively sending dividend to the investor, we ask them to "call" a witdrawDividend function - we chose "push" instead of "pull" approach. We calculate the eligible dividend for each investor right at the moment the tenant pays her rent to our smart contract. You can think of it like an amortization, then this eligible is available on demand, whenever the investor wants to withdraw his dividend, instead of periodly and actively distributed by us every month. This solution saves both us and the investors a lot of cost because they only pays gas fee when they withdraw (let's say they choose to withdraw every 3- 6 months, instead of every single month). We then created a modifier called updateDividendStatus to check and calculate the dividend balance before any dividend-related functions are executed to ensure there is no double-claim. Of course, we also addressed with standard problem like re-entrancy risk.
What we learned
Unfortunately, I couldn't find a team, some rejected me because I was a newbie (I printed "Hello World" 2 months ago). I learned a ton of things through all of the struggles to solve a lot of problems and make the app work. Some of problems are presented above. By building project, in addition to blockchain and smart contract knowledge, the biggest lesson is I learned how to think like a computer (not as human being) and solve programming problems.
This also confirmed my inspiration to start teaching myself how to code at the first place, programming is not just about writing lines of code, it all starts with the business logic and solution to a specific problem, writing codes will only work if we correctly nail the logic.
What's next for Fractional Real Estate
In this project, I simply focus on how practical an application can be. There are 2 metrics for this question:
Which part can be cryptographically trusted and practically implemented? Decentralized Chainlink price feed is the most practical and reliable one. Thus, I use it as a backbone to build a crypto payment solution for real estate.
How can we apply blockchain technology to the physical world?
DeFi landscape is now filled with DEX and digital projects like stable coin and lending protocols. But very little has been done with physical things like real estate. Thus, I tried to implement smart-contract capability as much as possible, in this case like: handling the sale, monthly dividend to provide cryptographically guarantee without a third-party like a bank.
There is still a human-involved part, like negotiate with bank to get the mortgage, finding a tenant...etc. I think we will gradually remove this part in the future. Until then, it is now practical to provide a fractional real estate backed by blockchain.
Built With
- hardhat
- javascript
- react
- solidity
Log in or sign up for Devpost to join the conversation.