-
Notifications
You must be signed in to change notification settings - Fork 42
NFT sketching #366
NFT sketching #366
Changes from 3 commits
07dc417
57f9afc
c6c14b3
6a3fc7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,28 @@ library DepositFunding { | |
using DepositLiquidation for DepositUtils.Deposit; | ||
using OutsourceDepositLogging for DepositUtils.Deposit; | ||
|
||
function isLocked() returns (bool) { | ||
return tbtcDrawn == 0; | ||
} | ||
|
||
function draw(uint amt) { | ||
require(amt == 1 tbtc, "partial draw not permitted"); | ||
mintTbtc(msg.sender, amt); | ||
drawn += amt; | ||
} | ||
|
||
function repay(uint amt) { | ||
require(amt == 1 tbtc, "partial repay not permitted"); | ||
burnTbtc(msg.sender, amt); | ||
drawn -= amt; | ||
} | ||
|
||
function setLocked(bool _locked) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notably, in the model I mention above, ownership transfers to the vending machine when an NFT is put in the vending machine, and locked vs unlocked might be a deposit state (one which the deposit moves out of during liquidation). If we went the deposit state path, we'd probably have four total states: There's an open question on the state side: can a deposit move between locked or unlocked during courtesy call? My take would be “sure, why not”, but interested in thoughts there as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's one more open thing here that I realized in chatting with @NicholasDotSol on his draft: we need the vending machine to be able to start locked deposit redemption, probably. There are really two ways to architect this: you send TBTC to the deposit and it hands it to the vending machine for burning, or you send TBTC to the vending machine and it has the deposit notify it of when to burn. The latter is simplest in that it is the same flow for locked and unlocked deposits, except that the vending machine and deposit both verify, for locked deposits, that the redeemer is the owner. Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is tough. quick term
Locked Deposits:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Shadowfiend re:
Redemption paths for locked deposits will be separate.
The vending machine in #364 envisions these scenarios as follows:
Note, the wrapper used in Ideally I'd like to do everything in Vending, no need for any further Deposit interactions. The vending machine handles TBTC - BTC deposit equilibrium by burning TBTC and DOTs (burning the DOTs here is good. Also leans out the vending machine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I finally gathered + summarized what you're describing in this comment. I'm on board with this. |
||
require(msg.sender == depositNft.ownerOf(this), "must be beneficiary"); | ||
require(drawn == 0, "deposit must be fully paid in tbtc"); | ||
locked = _locked; | ||
} | ||
|
||
/// @notice Deletes state after funding | ||
/// @dev This is called when we go to ACTIVE or setup fails without fraud | ||
function fundingTeardown(DepositUtils.Deposit storage _d) public { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
contract VendingMachine { | ||
function isQualified(deposit, proof) { | ||
// check deposit qualified | ||
totalValue = 0 | ||
unqualifiedDeposits = [...] | ||
for deposit in unqualifiedDeposits: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yikes. I knew tracking volume would be impractical... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ℹ️ I know this is just for demonstration and am not commenting on the code itself, just throwing ideas for how to get a number for maybe we could get Volume as a number updated every time a new deposit is qualified on the vending machine. We would also need a way to only count deposits created within each 6-block period. Note: this doesn't zero out, it just moved the range one block to the right. Need to figure out exactly what might affect this first. More info / digging needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, this doesn't really work. Having this number on vending machine does not take into account new deposits being created, so there is a pretty large lag. Instead if we take this approach we should use the Factory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another note: doing this in factory and tracking new Deposit instances opens the door for a DoS with current funder bond levels. Now the benefit of opening new deposits with no intentions of funding has the effect of increasing block qualification requirements for a pretty long time. If the block requirement is large enough there is a possibility that the function needed for proof will be too expensive to run. Timeout logic would need revision There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, this is what James was getting at re: minimum 1-conf tx's:
So one-conf makes sense here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Take a look at my 2nd pass, attention to
Took a stab at implementing this. It's not perfect. I'm wondering actually, why are we only guarding against reorgs for deposit funding, and not redemption too? cc @Shadowfiend It seems a re-org attack could be equally as damaging on redemption as it is on minting? Consider:
vs the funding scenario:
It seems in the latter, the miners can directly profit, but in the former it's only the signers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this week, let’s make sure to consider this volume mechanic to be on the back burner. We’ll pick it up later. Feel free to keep ideating, of course, it’s just not the main thing we want to deliver. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that's fair enough. Matt mentioned at planning it would be good to do it for funding as well, but not the first priority just yet. |
||
totalValue += deposit.lotSize | ||
|
||
blockReward = 12.5 | ||
minBlocksX = totalValue / blockReward | ||
|
||
proof = verifyProof(proof) | ||
|
||
// qualifier = 6 + n | ||
// where 6 is the minimum number of confs to mint tbtc and | ||
// n is the security margin that fluctuates according to opened deposit volume | ||
require(proof.blocks >= Math.min(6, minBlocksX)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this make sense to track in the deposit at all? One of the advantages of the vending machine to me is that the deposit needn't know about the token; all it's concerned with is what state the backing UTXO and signers are in.
In my mind, it makes more sense for the deposit to track its own transaction's proof state (e.g., I have/have not minted an NFT with 1 vs 2 vs 8 vs 1000 confirmations, etc). Proving more work can be done on the deposit, and the deposit can report how much work has been proven on its backing UTXO. I'm still getting my sea legs with Bitcoin terminology, so please don't hurt me if that sounds like a 5-year-old's mixing up of terms---hoping the core concept gets across.
Notably, both this sketch and #364 imply the vending machine is doing qualification. Instead, I think the vending machine can, given an NFT, ask its backing deposit “hey, can you meet these proof requirements?” Then the vending machine may want to provide some convenience code that lets you say “here is my deposit NFT + some additional proof”, but the proof is ultimately passed through to the deposit backing the NFT for verification + recording.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think tracking this in Deposit is the way to go. Took a while thinking about implications for having a
Drawn
variable or state. I'm not fully clear on whether this is intended to allow fractional drawing on larger lot sizes but assumingrequire(amt == 1)
==require(amt == lot Size)
A benefit of the vending machine is that it also restricts minting authority to just one contract. A simple query on the NFT and Deposit state can give the vending machine all the info it needs to mint or refuse minting.
Sitting with this for a while, I think I agree. This makes sense thematically and in terms of implementation. The proof state is technically knowledge of backing UTXO's proven work state, and can justifiably be stored in deposit state. Deposit's 1-proof functionality will also be very similar to Vending Machine's 6+x-proof therefore We can cut a lot of duplicated complexity from the Vending machine.
Note: This needs to be a public / external function callable only via the vending machine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Design-wise, I tend to agree with what you've said. Been doing some iteration today and I see that it's generally cleaner to centralise our token minting/burning in the vending machine.
Mmmmm. To follow on from that point, the vending machine only needs to know the BTC volume of unqualified TBTC flowing through. The actual qualification can be computed in the Deposit itself. This makes it a little easier too, in case we support different types of proofs ie. Lightning payments (#262).