-
Notifications
You must be signed in to change notification settings - Fork 42
Conversation
Pseudocode, regualr code and comments used to outline behaviour of an early vending machine
// return current number of blocks needed for qualification | ||
} | ||
|
||
// Use a DOT to obtain TBTC (ERC20) |
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.
What does DOT mean here?
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.
DOT = Deposit Owner Token
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.
👍 on this abbreviation. Makes things a bit clearer
// pay required TBTC to retrieve given DOT (in unredeemed state) | ||
function getDepositOwnerNFT(uint256 tokenid) public returns (address) { | ||
require(sended approved sufficient TBTC to be burned); | ||
if(tokenId == 0){ |
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.
For v1 I feel like we can require(tokenId != 0)
and force folks to claim specific NFTs. Someone (potentially us) can write a wrapper contract that handles any market making around which token to pull out when. 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.
I don't really like forcing to claim specific NFTs. I think we can create a pretty simple contract to determine redemption queue even without a real market. We can improve on it at a later stage. 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.
Three platitudes that convey my thoughts: complexity is bad, if it can be externalized it's better, and done is better than perfect 😁
I don't disagree with you that it's doable, but I don't think we lose much by not having this functionality available in a v1. Let's keep the possibility, but make it the last thing we do after the rest of the system is done.
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.
@Shadowfiend I like the platitudes, just saved them. 😃
I agree with Nich, a redemption queue would be rather simple/elegant. Right now, if two people redeem the same deposit, the higher gas payer will win. Since there's always 1:1 supply of TBTC and unlocked deposits, I'm not sure if a market would help here?
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.
To elaborate, I imagine the vending machine might just hold all DOT's that aren't otherwise exclusively owned (ie. forfeited redemption rights). This is a bit more efficient than destroying/recreating DOT's, if we were to do that. And then we could do something like:
tbtc2Dot() {
if(!depositOwnerTokenId) depositOwnerTokenId = publicDOTs.pop()
DepositOwnerToken.transferFrom(this, msg.sender, depositOwnerTokenId);
}
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.
The vending machine should absolutely own any DOTs that have had TBTC minted off of them.
Again, I don't disagree that this is doable---or even desirable! But I'm okay with leaving it aside for now and only adding it if there's time, for the simple reason that it's achievable with an external contract. I think we'll have our hands full already, and this is the kind of thing that will probably take longer to write good tests for than to write in the first place.
Keep in mind that by having deposit owner tokens in the first place, we have the ability to list deposits, filter to open ones, and filter to the ones that are owned by the vending machine. Whether we want to do that in a wrapper contract or in a dApp is another question of interest.
Regardless, I think it's worth holding and starting by requiring that you redeem a specific DOT.
// only in redemption Wrapper: getDepositOwnerNFT(RedemptionQueue.Next()) -- not async, cool. | ||
} | ||
// check vending machine for given NFT, revert if it doesn't exist. | ||
// transfer Deposit owner NFT |
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.
This is “transfer deposit owner NFT to msg.sender”, yes?
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.
yes it is
} | ||
|
||
// redeem a Dposit using an unredeemed DOT. not TBTC requirement | ||
function redeemDepositOwnerToken(uint256 TokenID) public { |
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.
Not sure I'm following this one. What does it do exactly?
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.
It's meant to be a way to redeem a Deposit using an unredeemed Deposit Owner Token. There should be a redemption flow for the folks opting out of minting fungible TBTC.
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.
Ah yes, of course. Redemption for unlocked tokens would still go through the vending machine because it requires burning TBTC, and we want the vending machine to manage that exclusively.
But there is a TBTC requirement in that case, no?
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.
I can redeem a Deposit Owner Token
for TBTC
, but I may chose not to. If I chose not to, the qualified Deposit Owner Token
is unredeemed and has a full TBTC
worth of value (since it is redeemable for that at any time) so there should be no TBTC
requirement here.
Not totally clear on fee handling though. Maybe provide fees with this call
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.
I finally understand some confusion I've had on a couple of your comments :)
The process of turning a DOT into TBTC should not be referred to as redemption. Redemption until now has been turning in TBTC and getting BTC, and for clarity's sake I think we should hold “redemption” to that exclusive meaning. Let's call the process you're referring to here as “redemption” as “minting TBTC off of a Deposit Owner Token”, or “turning a Deposit Owner Token in to the vending machine”. Similarly, if you go TBTC->DOT, let's call this “retrieving a Deposit Owner Token from the vending machine” or something like that.
In this approach, a Deposit Owner Token has no idea whether it's in the vending machine or not, it just changes owners. In fact, I'm a dumbo, and this means we don't need a locked/unlocked states. Deposits should always be locked to their owners. When someone mints TBTC off of a deposit, the deposit's ownership is transferred to the vending machine, allowing it to manage a future redemption transparently.
This leaves us with two flows in the vending machine:
- Redeeming a deposit owned by the vending machine. This requires 1 TBTC +
FEES
TBTC. - Redeeming a deposit not owned by the vending machine. This requires
FEES
TBTC.
I can see this being implemented as two public functions, or as one public function with a branch; I think that's up to you. -> I'm finally getting what @NicholasDotSol was going for in his PR + this comment in particular... Following up accordingly.
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.
Of note, the not-owned-by-the-vending-machine redemption flow can be mentally modeled as taking -> I'm finally getting what @NicholasDotSol was going for in his PR + this comment in particular... Following up accordingly.FEES
TBTC, minting 1 TBTC (which transfers ownership to the vending machine), then directly entering the “deposit owned by vending machine” redemption path with the resulting 1 TBTC + FEES
TBTC. The implementation should probably shortcut around some of this, of course.
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.
And now, to finally understanding the model from the other PR! Because the fee exchange for redemption does not require minting/burning authority, this lands us on an even simpler model, which is what the comment above is describing.
Deposit redemption is managed by the deposit, as today, but it only takes FEES
TBTC and distributes it. This is purely a TBTC transfer from the owner of TBTC to the signers.
- Redeeming a deposit owned by the vending machine requires, as noted in the above-linked comment, exchanging 1 TBTC for the deposit ownership token, then redeeming the underlying deposit (which can be wrapped in a helper later) with
FEES
TBTC. - Redeeming a deposit I own requires a standard redemption, sending
FEES
TBTC to the deposit. - Redeeming a deposit someone else owns requires acquiring ownership from them, or alternatively it requires waiting for liquidation to remove the ownership restriction.
Notably this doesn't require tracking any additional states in the deposit. The only thing we need to do is, when requesting redemption, if the deposit is not in a liquidation state, only the owner is allowed to redeem. If it is in a liquidation state (i.e., a state after courtesy call), anyone may redeem with FEES
TBTC.
This brings up the question of how this impacts the liquidation auction for deposits that are not owned by the vending machine ("locked deposits"). I think we need to pick that up next week, and can implement the first parts of this flow while leaving that to a separate consideration.
function isQualified(tokenId) public view returns (bool); | ||
|
||
// Qualify a DOT | ||
function qualifyDepositOwnerToken(tokenID, proofRequirements) public view returns (bool){ |
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.
@Shadowfiend, I would like the option to mint a qualified Deposit Owner Token before minting an unqualified 1-conf token. If a user has no need for immediate access The extra TX, time, and cost are all undesirable. I would personally take this option.
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.
I would file an issue for that. It's a nice-to-have, but seems straightforwardly accomplished with a wrapper contract if we don't have time to add it to the core functionality (simply by calling one function that calls both of the others).
I'm going to drop my final sense of how this might be structured at a high level, based on the two PRs: contract Deposit {
// Largely similar to the current situation, except that requesting
// redemption is disallowed in non-liquidation states unless you own
// the deposit. Redemption burns the associated deposit owner token.
// May provide a shortcut whereby when you add proof, if there is no
// associated DOT, it is automatically minted.
}
contract VendingMachine {
// Solely charged with taking ownership of deposits via their DOTs and
// returning TBTC.
// Contains its requirement for minimum deposit proof in order to produce TBTC.
// May provide shortcuts for adding proof to a deposit + minting TBTC off
// of its owner token in one go.
}
contract DepositOwnerToken is ERC721whateverwewant {
// Mints owner tokens off of a deposit.
// If we do 1+-conf minting here, we may provide a shortcut for adding
// proof + minting the owner token.
} I think we can ignore the shortcuts for now and focus on the bare bones of the functionality: allowing access to proof level of the deposit, allowing DOT minting from a deposit (let's ignore the confirmation requirement for now), allowing exchange of DOT for TBTC and vice versa (basic vending machine), and simplifying deposit's redemption to only handle the TBTC for fees (and guard for ownership in non-liquidation flows). Let's make that the aim for this week. One last note: this whole setup means we can't redeem a deposit if no one has minted TBTCs off of their DOTs. This is a known property of setting up the flow as it is. If there is a large need for deposit redemption, we would expect the price of TBTC to go up, thus incentivizing minting TBTC off of DOTs. Keep in mind the goal here is not to have the value of 1 TBTC equal that of 1 BTC at all times, but rather to know that 1 TBTC represents 1 BTC held by the system. |
early vending machine sketch using
pseudocode, regular code and comments to outline behavior
refs:
implementation planing: #344
parent / epic: #334