Sagres-waves v0.1 release: open source vesting smart contracts generator for WAVES blockchain
I'm releasing Sagres-waves v0.1, an open source web app for generation of vesting smart contracts for WAVES blockchain.
Sagres generator is live at sagres-waves.com
It can be used to define shmaht contracts for linear vesting schemes with max vesting period and vesting cliff at the start. Smart contract restricts withdrawal of predefined asset for individual WAVES accounts of project founders, investors, employees and consultants. An individual smart contract should be deployed for every account that needs vesting scheme.
Code and links
Sagres Github repo
Sagres website
Sagres 0.1 commits
Waves blockchain
RIDE smart contract language documentation
Sagres?
Sagres is a beautiful place in Portugal, where steep cliffs are shaped and eroded by waves. I find Sagres to be a fitting name for vesting contracts for WAVES blockchain.
Why?
Vesting is an important incentive design tool that can be used to align incentives of project co-founders, employees, consultants and investors.
Features
Sagres includes a vesting smart contract template that accepts a set of parameters and generates a RIDE smart contract that is designed to be attached to individual accounts of token holders.
Parameter | Description |
---|---|
startingUnixTimestampMsec | A starting date for vesting period |
originalAssetAmount | A starting amount of tokens for the given account |
assetId | asset ID |
ownerPk | account owner Public Key |
maxVestingPeriodWeeks | vesting period in weeks |
cliffPeriodWeeks | cliff period in weeks |
Smart contract template
let startingUnixTimestampMsec = ${startingUnixTimestampMsec}
let originalAssetAmount = ${originalAssetAmount}
let assetId = base58'${assetId}'
let ownerPk = base58'${ownerPk}'
match tx {
case tx:TransferTransaction =>
let txSenderIsOwner = ownerPk == tx.senderPk
let txSenderAddress = addressFromPublicKey(tx.senderPk)
let elapsedMsec = tx.timestamp - startingUnixTimestampMsec
let elapsedWeeks = elapsedMsec / 7 * 86400 * 1000
let vestingPeriodEnded = if elapsedWeeks > ${maxVestingPeriodWeeks} then true else false
let currentBalance = assetBalance(txSenderAddress, assetId)
let remainingBalanceAfterTx = currentBalance - tx.amount
let minRequiredAtTxTimestamp = if elapsedWeeks <= ${cliffPeriodWeeks} then originalAssetAmount
else originalAssetAmount * (${maxVestingPeriodWeeks} - elapsedWeeks / ${maxVestingPeriodWeeks} - ${cliffPeriodWeeks})
let vestingConditionsMatch = remainingBalanceAfterTx >= minRequiredAtTxTimestamp
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPk) && txSenderIsOwner && (vestingPeriodEnded || vestingConditionsMatch)
case burnTx:BurnTransaction => true
case _ => false
}
Example of generated smart contract
let startingUnixTimestampMsec = 1532214000000
let originalAssetAmount = 10000
let assetId = base58'EAhaYpFg9a3833aTgAxBBfLEKhP8yZkZ9qZpXDjBXUCg'
let ownerPk = base58'774ecw4Sk1tbqXS8RVvCorVEdW8ihmdysponYjfFHnm7'
match tx {
case tx:TransferTransaction =>
let txSenderIsOwner = ownerPk == tx.senderPk
let txSenderAddress = addressFromPublicKey(tx.senderPk)
let elapsedMsec = tx.timestamp - startingUnixTimestampMsec
let elapsedWeeks = elapsedMsec / 7 * 86400 * 1000
let vestingPeriodEnded = if elapsedWeeks > 12 then true else false
let currentBalance = assetBalance(txSenderAddress, assetId)
let remainingBalanceAfterTx = currentBalance - tx.amount
let minRequiredAtTxTimestamp = if elapsedWeeks <= 6 then originalAssetAmount
else originalAssetAmount * (12 - elapsedWeeks / 12 - 6)
let vestingConditionsMatch = remainingBalanceAfterTx >= minRequiredAtTxTimestamp
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPk) && txSenderIsOwner && (vestingPeriodEnded || vestingConditionsMatch)
case burnTx:BurnTransaction => true
case _ => false
}
Thank you for your contribution. I can see you have exposed Test Private and Public Key publicly, it's better not to do it.
For this inner if statement https://github.com/ontofractal/sagres_waves/blob/master/src/registerServiceWorker.js#L63, can it not be done in one if using AND operator.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
good info
Hey @ontofractal
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!