UNPKG

quasvel

Version:

Access and interact with Aragon Organizations and their apps.

253 lines (218 loc) 9.45 kB
import { BigInt, Address } from '@graphprotocol/graph-ts' import { ERC20 as ERC20Contract } from '../generated/templates/DisputableVoting/ERC20' import { Agreement as AgreementContract } from '../generated/templates/Agreement/Agreement' import { DisputableVoting as DisputableVotingEntity, Setting as SettingEntity, Vote as VoteEntity, CastVote as CastVoteEntity, Voter as VoterEntity, ERC20 as ERC20Entity } from '../generated/schema' import { DisputableVoting as VotingContract, NewSetting as NewSettingEvent, StartVote as StartVoteEvent, CastVote as CastVoteEvent, PauseVote as PauseVoteEvent, ResumeVote as ResumeVoteEvent, CancelVote as CancelVoteEvent, ExecuteVote as ExecuteVoteEvent, QuietEndingExtendVote as QuietEndingExtendVoteEvent, ChangeRepresentative as ChangeRepresentativeEvent } from '../generated/templates/DisputableVoting/DisputableVoting' /* eslint-disable @typescript-eslint/no-use-before-define */ export function handleNewSetting(event: NewSettingEvent): void { const votingApp = VotingContract.bind(event.address) const settingData = votingApp.getSetting(event.params.settingId) const voting = loadOrCreateVoting(event.address) const currentSettingId = buildSettingId(event.address, event.params.settingId) const setting = new SettingEntity(currentSettingId) setting.voting = event.address.toHexString() setting.settingId = event.params.settingId setting.voteTime = settingData.value0 setting.supportRequiredPct = settingData.value1 setting.minimumAcceptanceQuorumPct = settingData.value2 setting.delegatedVotingPeriod = settingData.value3 setting.quietEndingPeriod = settingData.value4 setting.quietEndingExtension = settingData.value5 setting.executionDelay = settingData.value6 setting.createdAt = event.block.timestamp setting.save() voting.setting = currentSettingId voting.save() } export function handleStartVote(event: StartVoteEvent): void { const voteId = buildVoteId(event.address, event.params.voteId) const voting = loadOrCreateVoting(event.address) const votingApp = VotingContract.bind(event.address) const vote = new VoteEntity(voteId) const voteData = votingApp.getVote(event.params.voteId) vote.voting = event.address.toHexString() vote.voteId = event.params.voteId vote.creator = event.params.creator vote.context = event.params.context.toString() vote.yeas = voteData.value0 vote.nays = voteData.value1 vote.totalPower = voteData.value2 vote.startDate = voteData.value3 vote.snapshotBlock = voteData.value4 vote.status = castVoteStatus(voteData.value5) vote.setting = buildSettingId(event.address, voteData.value6) vote.actionId = voteData.value7 vote.challengeId = BigInt.fromI32(0) vote.challenger = Address.fromString('0x0000000000000000000000000000000000000000') vote.challengeEndDate = BigInt.fromI32(0) vote.pausedAt = voteData.value8 vote.pauseDuration = voteData.value9 vote.quietEndingExtensionDuration = voteData.value10 vote.quietEndingSnapshotSupport = castVoterState(voteData.value11) vote.script = event.params.executionScript vote.settledAt = BigInt.fromI32(0) vote.disputedAt = BigInt.fromI32(0) vote.executedAt = BigInt.fromI32(0) vote.isAccepted = isAccepted(vote.yeas, vote.nays, vote.totalPower, vote.setting, votingApp.PCT_BASE()) vote.collateralRequirement = voting.collateralRequirement vote.save() } export function handleCastVote(event: CastVoteEvent): void { updateVoteState(event.address, event.params.voteId) const voter = loadOrCreateVoter(event.address, event.params.voter) voter.save() const votingApp = VotingContract.bind(event.address) const vote = VoteEntity.load(buildVoteId(event.address, event.params.voteId))! const miniMeToken = ERC20Contract.bind(votingApp.token()) const stake = miniMeToken.balanceOfAt(event.params.voter, vote.snapshotBlock) const castVote = loadOrCreateCastVote(event.address, event.params.voteId, event.params.voter) castVote.voter = voter.id castVote.stake = stake castVote.supports = event.params.supports castVote.createdAt = event.block.timestamp castVote.caster = event.params.caster castVote.save() } export function handlePauseVote(event: PauseVoteEvent): void { updateVoteState(event.address, event.params.voteId) const votingApp = VotingContract.bind(event.address) const agreementApp = AgreementContract.bind(votingApp.getAgreement()) const challengeData = agreementApp.getChallenge(event.params.challengeId) const vote = VoteEntity.load(buildVoteId(event.address, event.params.voteId))! vote.challenger = challengeData.value1 vote.challengeId = event.params.challengeId vote.challengeEndDate = challengeData.value2 vote.save() } export function handleResumeVote(event: ResumeVoteEvent): void { updateVoteState(event.address, event.params.voteId) } export function handleCancelVote(event: CancelVoteEvent): void { updateVoteState(event.address, event.params.voteId) } export function handleExecuteVote(event: ExecuteVoteEvent): void { updateVoteState(event.address, event.params.voteId) const vote = VoteEntity.load(buildVoteId(event.address, event.params.voteId))! vote.executedAt = event.block.timestamp vote.save() } export function handleQuietEndingExtendVote(event: QuietEndingExtendVoteEvent): void { updateVoteState(event.address, event.params.voteId) } export function handleChangeRepresentative(event: ChangeRepresentativeEvent): void { const voter = loadOrCreateVoter(event.address, event.params.voter) voter.representative = event.params.representative voter.save() } function isAccepted(yeas: BigInt, nays: BigInt, totalPower: BigInt, settingId: string, pctBase: BigInt): boolean { const setting = SettingEntity.load(settingId)! return hasReachedValuePct(yeas, yeas.plus(nays), setting.supportRequiredPct, pctBase) && hasReachedValuePct(yeas, totalPower, setting.minimumAcceptanceQuorumPct, pctBase) } function hasReachedValuePct(value: BigInt, total: BigInt, pct: BigInt, pctBase: BigInt): boolean { return total.notEqual(BigInt.fromI32(0)) && (value.times(pctBase).div(total)).gt(pct) } export function loadOrCreateVoting(votingAddress: Address): DisputableVotingEntity { let voting = DisputableVotingEntity.load(votingAddress.toHexString()) if (voting === null) { const votingApp = VotingContract.bind(votingAddress) voting = new DisputableVotingEntity(votingAddress.toHexString()) voting.dao = votingApp.kernel() voting.agreement = votingApp.getAgreement() voting.token = buildERC20(votingApp.token()) } return voting! } function loadOrCreateCastVote(votingAddress: Address, voteId: BigInt, voterAddress: Address): CastVoteEntity { const castVoteId = buildCastVoteId(votingAddress, voteId, voterAddress) let castVote = CastVoteEntity.load(castVoteId) if (castVote === null) { castVote = new CastVoteEntity(castVoteId) castVote.vote = buildVoteId(votingAddress, voteId) } return castVote! } function loadOrCreateVoter(votingAddress: Address, voterAddress: Address): VoterEntity { const voterId = buildVoterId(votingAddress, voterAddress) let voter = VoterEntity.load(voterId) if (voter === null) { voter = new VoterEntity(voterId) voter.voting = votingAddress.toHexString() voter.address = voterAddress } return voter! } export function updateVoteState(votingAddress: Address, voteId: BigInt): void { const votingApp = VotingContract.bind(votingAddress) const voteData = votingApp.getVote(voteId) const vote = VoteEntity.load(buildVoteId(votingAddress, voteId))! vote.yeas = voteData.value0 vote.nays = voteData.value1 vote.status = vote.status == 'Settled' ? 'Settled' : castVoteStatus(voteData.value5) vote.pausedAt = voteData.value8 vote.pauseDuration = voteData.value9 vote.quietEndingExtensionDuration = voteData.value10 vote.quietEndingSnapshotSupport = castVoterState(voteData.value11) vote.isAccepted = isAccepted(vote.yeas, vote.nays, vote.totalPower, vote.setting, votingApp.PCT_BASE()) vote.save() } export function buildERC20(address: Address): string { const id = address.toHexString() let token = ERC20Entity.load(id) if (token === null) { const tokenContract = ERC20Contract.bind(address) token = new ERC20Entity(id) token.name = tokenContract.name() token.symbol = tokenContract.symbol() token.decimals = tokenContract.decimals() token.save() } return token.id } export function buildVoteId(voting: Address, voteId: BigInt): string { return voting.toHexString() + "-vote-" + voteId.toString() } function buildVoterId(voting: Address, voter: Address): string { return voting.toHexString() + "-voter-" + voter.toHexString() } function buildCastVoteId(voting: Address, voteId: BigInt, voter: Address): string { return buildVoteId(voting, voteId) + "-cast-" + voter.toHexString() } function buildSettingId(voting: Address, settingId: BigInt): string { return voting.toHexString() + "-setting-" + settingId.toString() } function castVoterState(state: i32): string { switch (state) { case 0: return 'Absent' case 1: return 'Yea' case 2: return 'Nay' default: return 'Unknown' } } function castVoteStatus(state: i32): string { switch (state) { case 0: return 'Scheduled' case 1: return 'Challenged' case 2: return 'Cancelled' case 3: return 'Executed' default: return 'Unknown' } }