I would like to share with you an idea for a smart contract and would appreciate your feedback.
Alice has Bitcoins and other cryptos but needs urgently fiat to pay her bills. She could sell some BTC but she will lose money as the price fell from the time she bought.
Instead she uses a service that allows her to borrow NuBits for a month in exchange of collateral Bitcoins or other cryptos. The collaterial BTC are locked in a 2-of-2 multisig address where neither she or the service can access alone. The contact has a specific duration e.g. 1 month and she can return the borrowed NBT before the expire to get her locked funds back.
In case she defaults on her obligation (contract expires), the service can use a pre-signed timelocked “expire” transaction to unlock the funds by itself. The collateral is then auctioned to recover the original borrowed amount and the rest is returned to Alice.
This service would be a custodian that the shareholders will elect. The borrowed funds that are returned could be provably burned as fees or recycled for new contracts.
It would be possible for Alice to sell her contract in case she does not have the NuBits or wants to speculate due to the BTC/NBT price fluctuation.
The amount of collateral is decided by an algorithm if the Nubits provider are the Nu shareholders or the users themselves if they give their own NBT. Other parameters that influence the % of the collateral are the contract duration and the interest rate that the borrower pays.
- While it is impossible for the service to steal the coins from Alice without her consent, it is possible that the service refuses to co-sign her closing contract and wait for it to expire.
- If the contract expires, there is no guarantee that the service will be honest and return to her the coins left from the auction.
- In case the service’s private keys are compromised by Malice, she could spend the contract without returning the borrowed funds.
- The contract transaction ID changes thus the refund transaction becomes invalid and the service cannot make an auction of the expired contract. Worst case the service could lose Nubits.
- Alice sends coins to the contract but the service does not send her NuBits
To improve the security of the contract, a special script can be created that requires Alice’s signature plus 2-of-3 service signatures that we call oracles (they should belong to different custodians). Another characteristic that we want is the contract to remain inactive until Alice spends her Nubits.
To solve the situation where Alice sends Bitcoins to the contract but the service fails to send her NuBits, we add an Atomic cross-chain transfer feature to the contract. It works with Alice picking a secret value X and the hash of X is used in both the NuBits and Bitcoin transactions in a way that to spend them the original value X must be revealed. Both the transactions have a timeout so both parties can be refunded if the exchange was unsucessful. So when Alice spends the NuBits transaction, she reveals the value X and only then the service can use this value for the expire transaction to become active.
This is the P2SH redeem script of the Bitcoin contract:
HASH160 <hash of secret X> EQUALVERIFY <Alice's pubkey> CHECKSIGVERIFY 2 <Oracle's pubkey 1> <Oracle's pubkey 2> <Oracle's pubkey 3> 3 OP_CHECKMULTISIG
To spend this output the following script sig is needed:
0 <Oracle's signature 1> <Oracle's signature 2> <Alice's signature> <secret X> <The above redeem script>
The Nubits transaction should have the following P2SH script:
IF HASH160 <hash of secret X> EQUALVERIFY ELSE 2 <Oracle's pubkey 1> <Oracle's pubkey 2> <Oracle's pubkey 3> 3 OP_CHECKMULTISIGVERIFY ENDIF <Alice's pubkey> CHECKSIG
For Alice to spend this, she must use this script sig:
<Alice's signature> <secret X> 1 <The above redeem script>
Notice that she has to put the secret X in the transaction for it to work and this is how the service learns about this value and thus making the expire transaction spendable after the lock time passes.
For the service a timeout transaction will be created using this script sig:
<Alice's signature> 0 <Oracle's signature 1> <Oracle's signature 2> 0 <The above redeem script>
The above Nubits refund transaction is not perfectly safe due to transaction malleability. It can be solved by modifying the script to allow the oracles to spend the transaction without Alice or not providing a refund transaction for the Bitcoin deposit (can still be refunded by Alice + 2-of-3 oracles), both modifications require some extra trust. Another solution is to use CHECKLOCKTIMEVERIFY when it becomes available on the Nubits blockchain.
The custom smart contract, although not perfect, minimizes the trust needed and increases security compared to a classical exchange.
The downside of the custom scripts is that they are not standard and needs custom signing software. Alice could have a choice between a standard 2-of-2 multisig or the safer
1 + 2-of-3 + secretX contract.
Some more research needs to be done for a generic smart contract communication protocol. It is also possible to run this service/protocol on top of BitMessage or B&C exchange.
Thanks for reading and let me know if this is something of interest and what can be improved. I covered mostly the technical side and would like to know your opinion on how a service like could affect the NuBits liquidity.
Edit: Added a clarification about the collateral and the fact that this protocol can also run on the B&C exchange