Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vesting #214

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions abi/KaliDAOvesting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
[
{
"inputs": [],
"name": "AmountNotSpanMultiple",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "extensionData",
"type": "bytes"
}
],
"name": "callExtension",
"outputs": [
{
"internalType": "bool",
"name": "mint",
"type": "bool"
},
{
"internalType": "uint256",
"name": "amountOut",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "InsufficientAmount",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTimespan",
"type": "error"
},
{
"inputs": [],
"name": "NoArrayParity",
"type": "error"
},
{
"inputs": [],
"name": "NotDAO",
"type": "error"
},
{
"inputs": [],
"name": "NotVestee",
"type": "error"
},
{
"inputs": [],
"name": "Reentrancy",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "extensionData",
"type": "bytes"
}
],
"name": "setExtension",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "VestExceeded",
"type": "error"
},
{
"inputs": [],
"name": "VestNotStarted",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "dao",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "vestingId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "member",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amountOut",
"type": "uint256"
}
],
"name": "ExtensionCalled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "dao",
"type": "address"
},
{
"indexed": false,
"internalType": "address[]",
"name": "accounts",
"type": "address[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "startTimes",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "endTimes",
"type": "uint256[]"
}
],
"name": "ExtensionSet",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "vestings",
"outputs": [
{
"internalType": "address",
"name": "dao",
"type": "address"
},
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint128",
"name": "depositAmount",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "withdrawAmount",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "rate",
"type": "uint128"
},
{
"internalType": "uint64",
"name": "startTime",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "endTime",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
}
]
140 changes: 140 additions & 0 deletions components/newproposal/SetVesting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import React, { useState, useContext, useEffect } from 'react'
import Router, { useRouter } from 'next/router'
import AppContext from '../../context/AppContext'
import {
Input,
Button,
Text,
Textarea,
VStack,
Select,
Checkbox,
CheckboxGroup,
HStack,
Center,
} from '@chakra-ui/react'
import NumInputField from '../elements/NumInputField'
import DateSelect from '../elements/DateSelect'
import { addresses } from '../../constants/addresses'
import ProposalDescription from '../elements/ProposalDescription'
import { uploadIpfs } from '../../utils/helpers'
import { validateEns } from '../tools/ensHelpers'
import { toDecimals } from '../../utils/formatters'

export default function SetVesting() {
const value = useContext(AppContext)
const { web3, loading, account, abi, address, chainId, dao, daoChain } = value.state
const [startDate, setStartDate] = useState(new Date())

// For Notes section
const [doc, setDoc] = useState([])
const [note, setNote] = useState(null)
const [file, setFile] = useState(null)

const submitProposal = async (event) => {
event.preventDefault()
value.setLoading(true)

// Configure proposal type
const proposalType = 9

// Configure description param and upload to IPFS if necessary
let description
note && file
? (description = await uploadIpfs(dao.address, 'Set Vesting Proposal', file.name))
: (description = 'none')
note ? (description = note) : (description = 'none')
file ? (description = await uploadIpfs(dao.address, 'Set Vesting Proposal', file.name)) : null

// Configure account param
const vestingContract = addresses[daoChain]['extensions']['vesting']

let object = event.target

var array = []
for (let i = 0; i < object.length; i++) {
array[object[i].name] = object[i].value
}

var { account_, amount_, vestingStart_, vestingEnd_ } = array // this must contain any inputs from custom forms

// Validate address or ENS
account_ = await validateEns(account_, web3, value)
if (account_ === undefined) {
value.setLoading(false)
return
}

// Configure vesting start and end times for proposal payload
vestingStart_ = new Date(vestingStart_).getTime() / 1000
vestingEnd_ = new Date(vestingEnd_).getTime() / 1000

const timeDifference = vestingEnd_ - vestingStart_
amount_ = toDecimals(amount_, 18)

if (timeDifference == 0) {
value.toast('Invalid vesting period.')
return
}

if (amount_ % timeDifference != 0) {
console.log(timeDifference)
console.log(amount_ % timeDifference)
}

account_ = [account_]
amount_ = [0]
vestingStart_ = [vestingStart_]
vestingEnd_ = [vestingEnd_]

// Configure proposal payload
const payload_ = web3.eth.abi.encodeParameters(
['address[]', 'uint256[]', 'uint256[]', 'uint256[]'],
[account_, amount_, vestingStart_, vestingEnd_],
)

console.log(account_, amount_, vestingStart_, vestingEnd_)

try {
console.log(proposalType, description, vestingContract, payload_)
// const instance = new web3.eth.Contract(abi, address)
// let result = await instance.methods
// .propose(proposalType, description, [vestingContract], [1], [payload_])
// .send({ from: account })
// value.setVisibleView(2)
} catch (e) {
value.toast(e)
value.setLoading(false)
console.log(e)
}

value.setLoading(false)
}

return (
<form onSubmit={submitProposal}>
<VStack align={'flex-starte'}>
<Text>Recipient</Text>
<Input name="account_" placeholder="0xKALI or ENS"></Input>

<Text>Amount to Vest</Text>
<NumInputField name="amount_"></NumInputField>

<Text>Vesting Start</Text>
<DateSelect name="vestingStart_" />

<Text>Vesting End</Text>
<DateSelect name="vestingEnd_" />
</VStack>
<br />
<ProposalDescription doc={doc} setDoc={setDoc} note={note} setNote={setNote} setFile={setFile} />

<br />
<Center>
<Button className="solid-btn" type="submit">
Submit Proposal
</Button>
</Center>
</form>
)
}
5 changes: 5 additions & 0 deletions constants/addresses.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const addresses =
extensions: {
tribute: '0x561D9C4EdB64524556856133Bf7B5640dB904656',
crowdsale: '0xD76B629c528548582Af14c4D3a851830BB0c6978',
crowdsale2: '0xB677FA3DD5C2C0472f7520b48AA3F642F9c4Af11',
redemption: '0x3c9eB1c92b4063e6B9fA0531bC8966D3a09565D0',
manager: '0xeEffB992BE91B1FAC8C69bE4F2a8d5e334C02282',
},
Expand All @@ -28,8 +29,10 @@ export const addresses =
extensions: {
tribute: '0xd62AB72CC6b53D98eed510646a69B21b77ce5A56',
crowdsale: '0x30BF15b764A2A096c37f8c8E1b6b43D853db9a36',
crowdsale2: '0x2DCA7b86564Ade753062D6Cd60fb3a61fF1f2f9a',
redemption: '0x11f44975e1B204E50108Af6BCB6539798cb15F75',
manager: '0xCFAEA98787d835D127863ED4127F42d00F3D267d',
vesting: '0xB56440Ad1Aaf06824556F27299A44BC3A71a426f',
},
blockExplorer: 'https://rinkeby.etherscan.io',
},
Expand All @@ -44,6 +47,7 @@ export const addresses =
extensions: {
tribute: '0xAe3357E4D401495Cfe6e6022734E11293BC63dfb',
crowdsale: '0x0AE06840C05bf261B1798571696F58F9Ac3b3174',
crowdsale2: '0x77eC90818fD2116D29A7C39ea3D21808F09986EE',
redemption: '0xC43AE97f12d979FCAe346E93b62d747963956d63',
manager: '0x54e2b96d6f23B5ec8244054816fe3B33412c8538',
},
Expand All @@ -60,6 +64,7 @@ export const addresses =
extensions: {
tribute: '0xf1D291A527281049e66ABD3A41624B13D962868f',
crowdsale: '0x0bb3F43533FBf16d69dBdccf6AaAef81acd76FAB',
crowdsale2: '0x36a40E0e1581F9a5a6D6B52f5d064F5c8031068f',
redemption: '0x7452BDCED6f344e0E4e1169377D369aDE1cB0Ca0',
manager: '0xb47c9A6A494d344026C60c19C74f54f6AbA54fAa',
},
Expand Down
Loading