Created
February 21, 2022 19:46
-
-
Save sclearion/438df2c3bbc4b8779fec027b30830e96 to your computer and use it in GitHub Desktop.
Escrow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"valueParameterInfo":[["Collateral amount",{"valueParameterFormat":{"contents":[6,"₳"],"tag":"DecimalFormat"},"valueParameterDescription":"The amount of Lovelace to be deposited by both parties at the start of the contract to serve as an incentive for collaboration."}],["Price",{"valueParameterFormat":{"contents":[6,"₳"],"tag":"DecimalFormat"},"valueParameterDescription":"The amount of Lovelace to be paid by the _**Buyer**_ as part of the exchange."}]],"slotParameterDescriptions":[["Collateral deposit by seller timeout","The deadline by which the _**Seller**_ must deposit the _**Collateral amount**_ in the contract."],["Deposit of collateral by buyer timeout","The deadline by which the _**Buyer**_ must deposit the _**Collateral amount**_ in the contract."],["Deposit of price by buyer timeout","The deadline by which the _**Buyer**_ must deposit the _**Price**_ in the contract."],["Dispute by buyer timeout","The deadline by which, if the _**Buyer**_ has not opened a dispute, the _**Seller**_ will be paid."],["Complaint deadline","The deadline by which, if the _**Seller**_ has not responded to the dispute, the _**Buyer**_ will be refunded."]],"roleDescriptions":[["Buyer","The party that pays for the item on sale."],["Seller","The party that sells the item and gets the money if the exchange is successful."]],"contractType":"Escrow","contractShortDescription":"In this contract a _**seller**_ wants to sell an item (like a bicycle) to a _**buyer**_ for a _price_.","contractName":"Escrow with collateral","contractLongDescription":"In order to incentivise collaboration between the _**seller**_ and the _**buyer**_, at the beginning of the contract both parties deposit the _collateral amount_ that is burned if the parties disagree.","choiceInfo":[["Confirm problem",{"choiceFormat":{"contents":null,"tag":"DefaultFormat"},"choiceDescription":"Acknowledge that there was a problem and a refund must be granted."}],["Dispute problem",{"choiceFormat":{"contents":null,"tag":"DefaultFormat"},"choiceDescription":"The _**Seller**_ disagrees with the _**Buyer**_ about the claim that something went wrong and the collateral will be burnt."}],["Everything is alright",{"choiceFormat":{"contents":null,"tag":"DefaultFormat"},"choiceDescription":"The exchange was successful and the _**Buyer**_ agrees to pay the _**Seller**_."}],["Report problem",{"choiceFormat":{"contents":null,"tag":"DefaultFormat"},"choiceDescription":"The _**Buyer**_ claims not having received the product that was paid for as agreed and would like a refund."}]]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* We can set explicitRefunds true to run Close refund analysis | |
but we get a shorter contract if we set it to false */ | |
const explicitRefunds: Boolean = false; | |
const buyer: Party = Role("Buyer"); | |
const seller: Party = Role("Seller"); | |
const burnAddress: Party = PK("0000000000000000000000000000000000000000000000000000000000000000"); | |
const price: Value = ConstantParam("Price"); | |
const collateral: Value = ConstantParam("Collateral amount"); | |
const sellerCollateralTimeout: Timeout = SlotParam("Collateral deposit by seller timeout"); | |
const buyerCollateralTimeout: Timeout = SlotParam("Deposit of collateral by buyer timeout"); | |
const depositTimeout: Timeout = SlotParam("Deposit of price by buyer timeout"); | |
const disputeTimeout: Timeout = SlotParam("Dispute by buyer timeout"); | |
const answerTimeout: Timeout = SlotParam("Complaint deadline"); | |
function depositCollateral(party: Party, timeout: Timeout, timeoutContinuation: Contract, continuation: Contract): Contract { | |
return When([Case(Deposit(party, party, ada, collateral), continuation)], | |
timeout, | |
timeoutContinuation); | |
} | |
function burnCollaterals(continuation: Contract): Contract { | |
return Pay(seller, Party(burnAddress), ada, collateral, | |
Pay(buyer, Party(burnAddress), ada, collateral, | |
continuation)); | |
} | |
function deposit(timeout: Timeout, timeoutContinuation: Contract, continuation: Contract): Contract { | |
return When([Case(Deposit(seller, buyer, ada, price), continuation)], | |
timeout, | |
timeoutContinuation); | |
} | |
function choice(choiceName: string, chooser: Party, choiceValue: SomeNumber, continuation: Contract): Case { | |
return Case(Choice(ChoiceId(choiceName, chooser), | |
[Bound(choiceValue, choiceValue)]), | |
continuation); | |
} | |
function choices(timeout: Timeout, chooser: Party, timeoutContinuation: Contract, list: { value: SomeNumber, name: string, continuation: Contract }[]): Contract { | |
var caseList: Case[] = new Array(list.length); | |
list.forEach((element, index) => | |
caseList[index] = choice(element.name, chooser, element.value, element.continuation) | |
); | |
return When(caseList, timeout, timeoutContinuation); | |
} | |
function sellerToBuyer(continuation: Contract): Contract { | |
return Pay(seller, Account(buyer), ada, price, continuation); | |
} | |
function refundSellerCollateral(continuation: Contract): Contract { | |
if (explicitRefunds) { | |
return Pay(seller, Party(seller), ada, collateral, continuation); | |
} else { | |
return continuation; | |
} | |
} | |
function refundBuyerCollateral(continuation: Contract): Contract { | |
if (explicitRefunds) { | |
return Pay(buyer, Party(buyer), ada, collateral, continuation); | |
} else { | |
return continuation; | |
} | |
} | |
function refundCollaterals(continuation: Contract): Contract { | |
return refundSellerCollateral(refundBuyerCollateral(continuation)); | |
} | |
const refundBuyer: Contract = explicitRefunds ? Pay(buyer, Party(buyer), ada, price, Close) : Close; | |
const refundSeller: Contract = explicitRefunds ? Pay(seller, Party(seller), ada, price, Close) : Close; | |
const contract: Contract = | |
depositCollateral(seller, sellerCollateralTimeout, Close, | |
depositCollateral(buyer, buyerCollateralTimeout, refundSellerCollateral(Close), | |
deposit(depositTimeout, refundCollaterals(Close), | |
choices(disputeTimeout, buyer, refundCollaterals(refundSeller), | |
[{ value: 0n, name: "Everything is alright", continuation: refundCollaterals(refundSeller) }, | |
{ | |
value: 1n, name: "Report problem", | |
continuation: | |
sellerToBuyer( | |
choices(answerTimeout, seller, refundCollaterals(refundBuyer), | |
[{ value: 1n, name: "Confirm problem", continuation: refundCollaterals(refundBuyer) }, | |
{ value: 0n, name: "Dispute problem", continuation: burnCollaterals(refundBuyer) }])) | |
}])))); | |
return contract; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment