def run_trigger(new_logs): """ Template trigger """ events = [] for ev in get_events(new_logs): recipient, amount = decode_single('(address,uint256)', decode_hex(ev.data)) if amount == 0: continue contract_name = CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address) """ Event doesn't include token address, so if it's not from STRATCOMP, I have no idea what it might be. """ reward_token = '[UKNOWN]' if ev.address == STRATCOMP: reward_token = 'COMP' elif ev.address == STRAT3POOL: reward_token = 'CRV' events.append( event_normal("Reward tokens have been collected Γ°ΕΈβΒΈ", "{} {} has been collected by {}\n".format( format_token_human('COMP', amount), reward_token, contract_name, ), log_model=ev)) return events
def run_trigger(new_logs): """ Template trigger """ events = [] for ev in get_pause_events(new_logs): if ev.topic_0 == SIG_EVENT_YIELD_DISTRIBUTION: trustee, yield_amount, fee = decode_single( "(address,uint256,uint256)", decode_hex(ev.data)) events.append( event_low("Fee Distributed to Trustee Account π΄οΈ", "**Yield**: {}\n" "**Trustee**: {}\n" "**Fee**: {}".format( format_token_human('OUSD', Decimal(yield_amount)), trustee, format_token_human('OUSD', Decimal(fee)), ), log_model=ev)) elif ev.topic_0 == SIG_EVENT_TRUSTEE_ADDRESS_CHANGED: trustee = decode_single("(address)", decode_hex(ev.data))[0] events.append( event_low("Trustee Changed π΄οΈβ‘οΈπ΄οΈ", "**New Trustee**: {}".format(trustee), log_model=ev)) elif ev.topic_0 == SIG_EVENT_TRUSTEE_FEE_CHANGED: bps = decode_single("(uint256)", decode_hex(ev.data))[0] events.append( event_low("Trustee Fee Changed π²π΄οΈ", "**New Fee**: {}bps".format(bps), log_model=ev)) return events
def run_trigger(new_logs): """ Template trigger """ events = [] for ev in get_events(new_logs): asset = decode_single('(address)', decode_hex(ev.topic_1))[0] ptoken, amount = decode_single('(address,uint256)', decode_hex(ev.data)) asset_name = SYMBOL_FOR_CONTRACT.get(asset, asset) contract_name = CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address) if ev.topic_0 == SIG_EVENT_DEPOSIT: events.append( event_low("Deposit Γ°ΕΈβΒΌ", "{} {} was deposited to the {}\n\n".format( format_token_human(asset_name, amount), asset_name, contract_name, ), log_model=ev)) elif ev.topic_0 == SIG_EVENT_WITHDRAWAL: events.append( event_low("Withdrawal Γ°ΕΈβΒ½", "{} {} was withdrawn from the {}\n\n".format( format_token_human(asset_name, amount), asset_name, contract_name, ), log_model=ev)) else: # Theoretically impossible raise Exception('Unexpected event') return events
def run_trigger(new_logs): """ Template trigger """ events = [] for ev in get_events(new_logs): if ev.topic_0 == SIG_EVENT_START_VOTE: # StartVote( # uint256 indexed voteId, # address indexed creator, # string metadata, # uint256 minBalance, # uint256 minTime, # uint256 totalSupply, # uint256 creatorVotingPower # ) vote_id = decode_single('(uint256)', decode_hex(ev.topic_1))[0] creator = decode_single('(address)', decode_hex(ev.topic_2))[0] ( metadata_hash, min_balance, min_time, total_supply, creator_voting_power, ) = decode_single("(string,uint256,uint256,uint256,uint256)", decode_hex(ev.data)) metadata = fetch_ipfs_json( strip_terrible_ipfs_prefix(metadata_hash)) """ 51% Voting contract is for contract deployments and 60% Voting contract is for parameter changes """ vote_url = 'https://dao.curve.fi/vote/{}/{}'.format( 'ownership' if ev.address == CURVE_ARAGON_51 else 'parameter', vote_id, ) details = ("**Creator**: {} \n" "**Creator Voting Power**: {} veCRV\n" "**Minimum vote balance**: {} veCRV\n" "**Current total supply**: {} veCRV\n" "**Minimum time**: {}\n" "**Metadata**: {}\n\n" "{}").format( creator, format_token_human('veCRV', creator_voting_power), format_token_human('veCRV', min_balance), format_token_human('veCRV', total_supply), format_timedelta(timedelta(seconds=min_time)), metadata.get('text', 'NO METADATA TEXT FOUND.'), vote_url, ) events.append( event_high("{} - Vote Created ({}) π³οΈ π".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address), vote_id, ), details, log_model=ev)) elif ev.topic_0 == SIG_EVENT_EXECUTE_VOTE: # ExecuteVote(uint256 indexed voteId) vote_id = decode_single('(uint256)', decode_hex(ev.topic_1))[0] events.append( event_high( "{} - Vote Executed ({}) π³οΈ βοΈ".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address), vote_id, ), "Curve Aragon DAO vote #{} on the {} voting app has been " "executed".format( vote_id, CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address), ), log_model=ev)) elif ev.topic_0 == SIG_EVENT_SCRIPT_RESULT: # ScriptResult( # address indexed executor, # bytes script, # bytes input, # bytes returnData # ) executor = decode_single('(address)', decode_hex(ev.topic_1))[0] # script, input_data, return_data = decode_single( # "(bytes,bytes,bytes)", # decode_hex(ev.data), # ) """ TODO: Decode this further? Right now I don't think it's worth the effort, though we're putting a bit of trust into the prop that it's nothing nefarious. Might be worth coming back to this. Only problem is that it appears to be EVM-level instructions... Ref: https://hack.aragon.org/docs/evmscript_EVMScriptRunner Ref: https://github.com/aragon/aragonOS/blob/f3ae59b00f73984e562df00129c925339cd069ff/contracts/evmscript/EVMScriptRunner.sol#L34-L100 """ # print('script', script) # print('input_data:', input_data) # print('return_data:', return_data) events.append( event_normal("{} - Execution Result π³οΈ πͺ£".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "Executed by: {}".format(executor), log_model=ev)) return events
def run_trigger(new_logs): """ Template trigger """ events = [] for ev in get_events(new_logs): if ev.topic_0 == SIG_EVENT_CHANGE_SUPPORT_REQUIRED: # ChangeSupportRequired(uint64 supportRequiredPct) support_required = decode_single('(uint64)', decode_hex(ev.data))[0] events.append( event_high( "{} - Support Required Changed ποΈ".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "{}% support is now required for a vote pass. \n\n" "NOTE: This is unexpected due to two contracts for different " "voting levels.".format(Decimal(support_required) / E_18), log_model=ev)) elif ev.topic_0 == SIG_EVENT_CHANGE_MIN_QUORUM: # ChangeMinQuorum(uint64 minAcceptQuorumPct) min_quorum = decode_single('(uint64)', decode_hex(ev.data))[0] events.append( event_normal( "{} - Support Minimum Quorum ποΈ".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "{}% quorum (yeas out of total supply) is now required for a vote." .format(Decimal(min_quorum) / E_18), log_model=ev)) elif ev.topic_0 == SIG_EVENT_MIN_BALANCE_SET: # MinimumBalanceSet(uint256 minBalance) min_balance = decode_single('(uint256)', decode_hex(ev.data))[0] events.append( event_normal( "{} - Minimum Balance ποΈ".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "Minimum balance of {} is now required to create a governance " "vote.".format(format_token_human('veCRV', min_balance)), log_model=ev)) elif ev.topic_0 == SIG_EVENT_MIN_TIME_SET: # MinimumTimeSet(uint256 minTime) min_time = decode_single('(uint256)', decode_hex(ev.data))[0] events.append( event_normal( "{} - Minimum Time π".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "Governance vote creation rate limit has been changed to " "{}.".format(format_timedelta( timedelta(seconds=min_time))), log_model=ev)) elif ev.topic_0 == SIG_EVENT_SET_APP: # SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app) namespace = decode_single('(bytes32)', decode_hex(ev.topic_1))[0] app_id = decode_single('(bytes32)', decode_hex(ev.topic_1))[0] app_address = decode_single('(address)', decode_hex(ev.data))[0] events.append( event_high( "{} - New App Set π".format( CONTRACT_ADDR_TO_NAME.get(ev.address, ev.address)), "A new Aragon app has been set for the Curve Voting Fork. " "This is expected to only happen on app creation.\n\n" "Namespace: {}\n" "App ID: {}\n" "App Address: {}\n".format( namespace, app_id, app_address, ), log_model=ev)) return events
def run_trigger(new_logs): """ Compound Timelock changes """ events = [] for ev in get_events(new_logs): if ev.topic_0 == SIG_EVENT_AAVE_PROPOSAL_CREATED: """ event ProposalCreated( uint256 indexed proposalId, bytes32 indexed ipfsHash, bytes32 indexed proposalType, uint256 propositionPowerOfCreator, uint256 threshold, uint256 maxMovesToVotingAllowed, uint256 votingBlocksDuration, uint256 validatingBlocksDuration, address proposalExecutor ) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] ipfs_hash = decode_single("(bytes32)", decode_hex(ev.topic_2))[0] # proposal_type = decode_single( # "(bytes32)", # decode_hex(ev.topic_3) # )[0] ( proposition_power_of_creator, threshold, max_moves_to_voting_allowed, voting_blocks_duration, validating_blocks_duration, proposal_executor, ) = decode_single( "(uint256,uint256,uint256,uint256,uint256,address)", decode_hex(ev.data)) b58_ipfs_data = decode_ipfs_hash(encode_hex(ipfs_hash)) ipfs_data = fetch_ipfs_json(b58_ipfs_data) prop_headers = parse_prop_headers(ipfs_data) aip = prop_headers.get('aip') if aip: aip_link = 'https://aave.github.io/aip/AIP-{}'.format(aip) else: aip_link = '[UNKNOWN AIP]' events.append( event_high( "Aave (v1) Governance Proposal Created (ID: {}) π³οΈ π". format(proposal_id), "A new proposal (ID: {}) has been submitted for Aave" "\n\n" "**Title**: {}\n" "**Description**: {}\n\n" "**Threshold**: {} AAVE\n" "**Voting Duration** {} blocks (approx {} days)\n" "**Validating Duration** {} blocks (approx {} days)\n" "**Executor**: {}\n" "**IPFS Hash**: {}\n" "{}".format( proposal_id, ipfs_data.get('title'), ipfs_data.get('shortDescription'), format_token_human('AAVE', Decimal(threshold)), voting_blocks_duration, round( Decimal(voting_blocks_duration) / BLOCKS_PER_DAY, 2), validating_blocks_duration, round( Decimal(validating_blocks_duration) / BLOCKS_PER_DAY, 2), proposal_executor, decode_ipfs_hash(encode_hex(ipfs_hash)), aip_link, ), log_model=ev)) elif ev.topic_0 == SIG_EVENT_STATUS_CHANGE_TO_VALIDATING: # StatusChangeToValidating(uint256 indexed proposalId) proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_high( "Aave proposal moved to validating π³οΈ π", "Aave proposal #{} is now in validating stage awaiting " "challenges".format(proposal_id), log_model=ev)) elif ev.topic_0 == SIG_EVENT_STATUS_CHANGE_TO_VOTING: """ StatusChangeToVoting( uint256 indexed proposalId, uint256 movesToVoting ) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_high("Aave proposal moved to voting π³οΈ π₯", "Aave proposal #{} is now in voting stage".format( proposal_id), log_model=ev)) elif ev.topic_0 == SIG_EVENT_STATUS_CHANGE_TO_EXECUTED: """ StatusChangeToExecuted(uint256 indexed proposalId) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_normal("Aave proposal has been resolved π³οΈ βοΈ", "Aave proposal #{} has now been resolved".format( proposal_id), log_model=ev)) elif ev.topic_0 == SIG_EVENT_WINS_YES: """ YesWins( uint256 indexed proposalId, uint256 abstainVotingPower, uint256 yesVotingPower, uint256 noVotingPower ) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_high( "Aave proposal has been passed π³οΈ β ", "Aave proposal #{} has been passed".format(proposal_id), log_model=ev)) elif ev.topic_0 == SIG_EVENT_WINS_NO: """ NoWins( uint256 indexed proposalId, uint256 abstainVotingPower, uint256 yesVotingPower, uint256 noVotingPower ) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_high( "Aave proposal has failed π³οΈ β", "Aave proposal #{} has been rejected".format(proposal_id), log_model=ev)) elif ev.topic_0 == SIG_EVENT_WINS_ABSTAIN: """ AbstainWins( uint256 indexed proposalId, uint256 abstainVotingPower, uint256 yesVotingPower, uint256 noVotingPower ) """ proposal_id = decode_single("(uint256)", decode_hex(ev.topic_1))[0] events.append( event_high( "Aave proposal has failed by abstention π³οΈ γ°οΈ", "Aave proposal #{} has been rejected by abstention".format( proposal_id), log_model=ev)) return events