import { ethereum , BigInt , Address } from '@graphprotocol/graph-ts' ; import { ERC20 } from '../generated/schema' ; import { ERC20 as ERC20Contract } from '../generated/templates/Agreement/ERC20' ; import { Staking as StakingContract } from '../generated/templates/Agreement/Staking' ; import { StakingFactory as StakingFactoryContract } from '../generated/templates/Agreement/StakingFactory' ; import { Agreement , Action , Signature , Version , Disputable , Challenge , Dispute , Evidence , Signer , CollateralRequirement , ArbitratorFee , StakingMovement , Staking } from '../generated/schema' ; import { Agreement as AgreementContract , ActionSubmitted , ActionChallenged , ActionSettled , ActionDisputed , ActionAccepted , ActionVoided , ActionRejected , ActionClosed , EvidenceSubmitted , SettingChanged , Signed , DisputableAppActivated , DisputableAppDeactivated , CollateralRequirementChanged } from '../generated/templates/Agreement/Agreement' ; export function handleSettingChanged ( event ) { const agreementApp = AgreementContract . bind ( event . address ) ; const settingData = agreementApp . getSetting ( event . params . settingId ) ; const agreement = loadOrCreateAgreement ( event . address ) ; const currentVersionId = buildVersionId ( event . address , event . params . settingId ) ; const version = new Version ( currentVersionId ) ; version . agreement = event . address . toHexString ( ) ; version . versionId = event . params . settingId ; version . arbitrator = settingData . value0 ; version . appFeesCashier = settingData . value1 ; version . title = settingData . value2 ; version . content = settingData . value3 ; version . effectiveFrom = event . block . timestamp ; version . save ( ) ; agreement . currentVersion = currentVersionId ; agreement . save ( ) ; } export function handleSigned ( event ) { const signer = loadOrCreateSigner ( event . address , event . params . signer ) ; signer . save ( ) ; const signature = new Signature ( event . transaction . hash . toHexString ( ) ) ; signature . signer = buildSignerId ( event . address , event . params . signer ) ; signature . version = buildVersionId ( event . address , event . params . settingId ) ; signature . createdAt = event . block . timestamp ; signature . save ( ) ; } export function handleDisputableAppActivated ( event ) { const agreementApp = AgreementContract . bind ( event . address ) ; const disputableData = agreementApp . getDisputableInfo ( event . params . disputable ) ; const disputable = loadOrCreateDisputable ( event . address , event . params . disputable ) ; disputable . activated = true ; disputable . currentCollateralRequirement = buildCollateralRequirementId ( event . address , event . params . disputable , disputableData . value1 ) ; disputable . save ( ) ; updateCollateralRequirement ( event . address , event . params . disputable , disputableData . value1 ) ; } export function handleDisputableAppDeactivated ( event ) { const disputable = loadOrCreateDisputable ( event . address , event . params . disputable ) ; disputable . activated = false ; disputable . save ( ) ; } export function handleCollateralRequirementChanged ( event ) { updateCollateralRequirement ( event . address , event . params . disputable , event . params . collateralRequirementId ) ; } export function handleActionSubmitted ( event ) { const actionId = buildActionId ( event . address , event . params . actionId ) ; const agreementApp = AgreementContract . bind ( event . address ) ; const action = new Action ( actionId ) ; const actionData = agreementApp . getAction ( event . params . actionId ) ; action . agreement = event . address . toHexString ( ) ; action . actionId = event . params . actionId ; action . disputable = buildDisputableId ( event . address , actionData . value0 ) ; action . disputableActionId = actionData . value1 ; action . collateralRequirement = buildCollateralRequirementId ( event . address , actionData . value0 , actionData . value2 ) ; action . version = buildVersionId ( event . address , actionData . value3 ) ; action . submitter = buildSignerId ( event . address , actionData . value4 ) ; action . closed = actionData . value5 ; action . context = actionData . value6 ; action . createdAt = event . block . timestamp ; action . save ( ) ; createStakingMovement ( event . address , event . params . actionId , 'new' , event ) ; } export function handleActionClosed ( event ) { const action = Action . load ( buildActionId ( event . address , event . params . actionId ) ) ! ; action . closed = true ; action . save ( ) ; createStakingMovement ( event . address , event . params . actionId , 'closed' , event ) ; } export function handleActionChallenged ( event ) { const actionId = buildActionId ( event . address , event . params . actionId ) ; const challengeId = buildChallengeId ( event . address , event . params . challengeId ) ; const agreementApp = AgreementContract . bind ( event . address ) ; const action = Action . load ( actionId ) ! ; action . lastChallenge = challengeId ; action . save ( ) ; const challenge = new Challenge ( challengeId ) ; const challengeData = agreementApp . getChallenge ( event . params . challengeId ) ; challenge . action = buildActionId ( event . address , event . params . actionId ) ; challenge . challengeId = event . params . challengeId ; challenge . challenger = challengeData . value1 ; challenge . endDate = challengeData . value2 ; challenge . context = challengeData . value3 ; challenge . settlementOffer = challengeData . value4 ; challenge . state = castChallengeState ( challengeData . value5 ) ; challenge . createdAt = event . block . timestamp ; const challengerArbitratorFeeId = challengeId + 'challenger-arbitrator-fee' ; const challengeArbitratorFeesData = agreementApp . getChallengeArbitratorFees ( event . params . challengeId ) ; createArbitratorFee ( event . address , challengerArbitratorFeeId , challengeArbitratorFeesData . value2 , challengeArbitratorFeesData . value3 ) ; challenge . challengerArbitratorFee = challengerArbitratorFeeId ; challenge . save ( ) ; createStakingMovement ( event . address , event . params . actionId , 'challenged' , event ) ; } export function handleActionSettled ( event ) { updateChallengeState ( event . address , event . params . challengeId ) ; createStakingMovement ( event . address , event . params . actionId , 'settled' , event ) ; } export function handleActionDisputed ( event ) { updateChallengeState ( event . address , event . params . challengeId ) ; const dispute = loadOrCreateDispute ( event . address , event . params . challengeId , event ) ; dispute . save ( ) ; const challengeId = buildChallengeId ( event . address , event . params . challengeId ) ; const agreementApp = AgreementContract . bind ( event . address ) ; const challengeArbitratorFeesData = agreementApp . getChallengeArbitratorFees ( event . params . challengeId ) ; const submitterArbitratorFeeId = challengeId + 'submitter-arbitrator-fee' ; createArbitratorFee ( event . address , submitterArbitratorFeeId , challengeArbitratorFeesData . value0 , challengeArbitratorFeesData . value1 ) ; const challenge = Challenge . load ( challengeId ) ! ; challenge . submitterArbitratorFee = submitterArbitratorFeeId ; challenge . save ( ) ; } export function handleActionAccepted ( event ) { updateChallengeState ( event . address , event . params . challengeId ) ; updateDisputeState ( event . address , event . params . challengeId , event ) ; } export function handleActionVoided ( event ) { updateChallengeState ( event . address , event . params . challengeId ) ; updateDisputeState ( event . address , event . params . challengeId , event ) ; } export function handleActionRejected ( event ) { updateChallengeState ( event . address , event . params . challengeId ) ; updateDisputeState ( event . address , event . params . challengeId , event ) ; createStakingMovement ( event . address , event . params . actionId , 'rejected' , event ) ; } export function handleEvidenceSubmitted ( event ) { const evidenceId = buildId ( event ) ; const evidence = new Evidence ( evidenceId ) ; evidence . data = event . params . evidence ; evidence . dispute = buildDisputeId ( event . address , event . params . disputeId ) ; evidence . submitter = event . params . submitter ; evidence . createdAt = event . block . timestamp ; evidence . save ( ) ; } function loadOrCreateAgreement ( agreementAddress ) { let agreement = Agreement . load ( agreementAddress . toHexString ( ) ) ; if ( agreement === null ) { const agreementApp = AgreementContract . bind ( agreementAddress ) ; const stakingFactoryAddress = agreementApp . stakingFactory ( ) ; agreement = new Agreement ( agreementAddress . toHexString ( ) ) ; agreement . dao = agreementApp . kernel ( ) ; agreement . stakingFactory = stakingFactoryAddress ; } return agreement ! ; } function loadOrCreateSigner ( agreement , signerAddress ) { const signerId = buildSignerId ( agreement , signerAddress ) ; let signer = Signer . load ( signerId ) ; if ( signer === null ) { signer = new Signer ( signerId ) ; signer . agreement = agreement . toHexString ( ) ; signer . address = signerAddress ; } return signer ! ; } function loadOrCreateDisputable ( agreement , disputableAddress ) { const disputableId = buildDisputableId ( agreement , disputableAddress ) ; let disputable = Disputable . load ( disputableId ) ; if ( disputable === null ) { disputable = new Disputable ( disputableId ) ; disputable . agreement = agreement . toHexString ( ) ; disputable . address = disputableAddress ; } return disputable ! ; } function loadOrCreateDispute ( agreement , challengeId , event ) { const agreementApp = AgreementContract . bind ( agreement ) ; const challengeData = agreementApp . getChallenge ( challengeId ) ; const disputeId = buildDisputeId ( agreement , challengeData . value8 ) ; let dispute = Dispute . load ( disputeId ) ; if ( dispute === null ) { dispute = new Dispute ( disputeId ) ; dispute . ruling = challengeData . value9 ; dispute . disputeId = challengeData . value8 ; dispute . challenge = buildChallengeId ( agreement , challengeId ) ; dispute . submitterFinishedEvidence = challengeData . value6 ; dispute . challengerFinishedEvidence = challengeData . value7 ; dispute . createdAt = event . block . timestamp ; } return dispute ! ; } function updateChallengeState ( agreement , challengeId ) { const agreementApp = AgreementContract . bind ( agreement ) ; const challengeData = agreementApp . getChallenge ( challengeId ) ; const challenge = Challenge . load ( buildChallengeId ( agreement , challengeId ) ) ! ; challenge . state = castChallengeState ( challengeData . value5 ) ; challenge . save ( ) ; } function updateDisputeState ( agreement , challengeId , event ) { const agreementApp = AgreementContract . bind ( agreement ) ; const challengeData = agreementApp . getChallenge ( challengeId ) ; const dispute = loadOrCreateDispute ( agreement , challengeId , event ) ; dispute . ruling = challengeData . value9 ; dispute . submitterFinishedEvidence = challengeData . value6 ; dispute . challengerFinishedEvidence = challengeData . value7 ; dispute . save ( ) ; } function updateCollateralRequirement ( agreement , disputable , collateralRequirementId ) { const agreementApp = AgreementContract . bind ( agreement ) ; const requirementId = buildCollateralRequirementId ( agreement , disputable , collateralRequirementId ) ; const requirement = new CollateralRequirement ( requirementId ) ; const requirementData = agreementApp . getCollateralRequirement ( disputable , collateralRequirementId ) ; requirement . disputable = buildDisputableId ( agreement , disputable ) ; requirement . token = buildERC20 ( agreement , requirementData . value0 ) ; requirement . challengeDuration = requirementData . value1 ; requirement . actionAmount = requirementData . value2 ; requirement . challengeAmount = requirementData . value3 ; requirement . save ( ) ; } function createStakingMovement ( agreement , actionId , type , event ) { const agreementApp = AgreementContract . bind ( agreement ) ; const actionData = agreementApp . getAction ( actionId ) ; const collateralData = agreementApp . getCollateralRequirement ( actionData . value0 , actionData . value2 ) ; const user = actionData . value4 ; const token = collateralData . value0 ; const collateralAmount = collateralData . value2 ; if ( collateralAmount . equals ( BigInt . fromI32 ( 0 ) ) ) { return ; } const factory = StakingFactoryContract . bind ( agreementApp . stakingFactory ( ) ) ; const stakingAddress = factory . getInstance ( token ) ; const staking = updateStaking ( stakingAddress , token , user ) ; const id = buildStakingMovementId ( token , user , buildId ( event ) ) ; const movement = new StakingMovement ( id ) ; movement . staking = staking . id ; movement . agreement = agreement . toHexString ( ) ; movement . action = buildActionId ( agreement , actionId ) ; movement . createdAt = event . block . timestamp ; if ( type == 'new' ) { movement . amount = collateralAmount ; movement . actionState = 'Scheduled' ; movement . collateralState = 'Locked' ; } else if ( type == 'challenged' ) { movement . amount = collateralAmount ; movement . actionState = 'Challenged' ; movement . collateralState = 'Challenged' ; staking . challenged = staking . challenged . plus ( collateralAmount ) ; } else if ( type == 'settled' ) { const challengeData = agreementApp . getChallenge ( actionData . value7 ) ; movement . amount = challengeData . value4 ; movement . actionState = 'Settled' ; movement . collateralState = 'Slashed' ; staking . challenged = staking . challenged . minus ( collateralAmount ) ; } else if ( type == 'rejected' ) { movement . amount = collateralAmount ; movement . actionState = 'Cancelled' ; movement . collateralState = 'Slashed' ; staking . challenged = staking . challenged . minus ( collateralAmount ) ; } else { movement . amount = collateralAmount ; movement . actionState = 'Completed' ; movement . collateralState = 'Available' ; staking . challenged = staking . challenged . minus ( collateralAmount ) ; } staking . save ( ) ; movement . save ( ) ; } function updateStaking ( stakingAddress , token , user ) { const stakingApp = StakingContract . bind ( stakingAddress ) ; const balance = stakingApp . getBalancesOf ( user ) ; const staking = loadOrCreateStaking ( token , user ) ; staking . total = balance . value0 ; staking . locked = balance . value1 ; staking . available = staking . total . minus ( staking . locked ) ; staking . save ( ) ; return staking ; } function loadOrCreateStaking ( token , user ) { const id = buildStakingId ( token , user ) ; let staking = Staking . load ( id ) ; if ( staking === null ) { staking = new Staking ( id ) ; staking . user = user ; staking . token = token . toHexString ( ) ; staking . total = BigInt . fromI32 ( 0 ) ; staking . locked = BigInt . fromI32 ( 0 ) ; staking . available = BigInt . fromI32 ( 0 ) ; staking . challenged = BigInt . fromI32 ( 0 ) ; } return staking ! ; } function createArbitratorFee ( agreement , id , feeToken , feeAmount ) { const arbitratorFee = new ArbitratorFee ( id ) ; arbitratorFee . amount = feeAmount ; arbitratorFee . token = buildERC20 ( agreement , feeToken ) ; arbitratorFee . save ( ) ; } export function buildERC20 ( agreement , address ) { const id = address . toHexString ( ) ; let token = ERC20 . load ( id ) ; if ( token === null ) { const tokenContract = ERC20Contract . bind ( address ) ; token = new ERC20 ( id ) ; token . name = tokenContract . name ( ) ; token . symbol = tokenContract . symbol ( ) ; token . decimals = tokenContract . decimals ( ) ; token . save ( ) ; } return token . id ; } function buildSignerId ( agreement , signer ) { return agreement . toHexString ( ) + "-signer-" + signer . toHexString ( ) ; } function buildDisputableId ( agreement , disputable ) { return agreement . toHexString ( ) + "-disputable-" + disputable . toHexString ( ) ; } export function buildActionId ( agreement , actionId ) { return agreement . toHexString ( ) + "-action-" + actionId . toString ( ) ; } function buildChallengeId ( agreement , challengeId ) { return agreement . toHexString ( ) + "-challenge-" + challengeId . toString ( ) ; } function buildDisputeId ( agreement , disputeId ) { return agreement . toHexString ( ) + "-dispute-" + disputeId . toString ( ) ; } function buildVersionId ( agreement , versionId ) { return agreement . toHexString ( ) + "-version-" + versionId . toString ( ) ; } function buildCollateralRequirementId ( agreement , disputable , collateralRequirementId ) { return buildDisputableId ( agreement , disputable ) + "-collateral-requirement-" + collateralRequirementId . toString ( ) ; } function buildStakingId ( token , user ) { return token . toHexString ( ) + "-staking-" + user . toHexString ( ) ; } function buildStakingMovementId ( token , user , id ) { return buildStakingId ( token , user ) + "-movement-" + id ; } function buildId ( event ) { return event . transaction . hash . toHexString ( ) + event . logIndex . toString ( ) ; } function castChallengeState ( state ) { switch ( state ) { case 0 : return 'Waiting' ; case 1 : return 'Settled' ; case 2 : return 'Disputed' ; case 3 : return 'Rejected' ; case 4 : return 'Accepted' ; case 5 : return 'Voided' ; default : return 'Unknown' ; } }