Skip to content

Commit

Permalink
add assertion failed in oo state
Browse files Browse the repository at this point in the history
Signed-off-by: ryanwolhuter <[email protected]>
  • Loading branch information
ryanwolhuter committed Oct 18, 2023
1 parent 6762b3c commit 5c91513
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 18 deletions.
10 changes: 10 additions & 0 deletions src/plugins/oSnap/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ function enhanceTokensWithBalances(
balances: Partial<BalanceResponse>[],
tokens: Token[]
) {
console.log({ balances, tokens });
return balances
.filter(
(balance): balance is BalanceResponse =>
Expand Down Expand Up @@ -147,6 +148,7 @@ async function fetchCollectibles(network: Network, gnosisSafeAddress: string) {
network,
gnosisSafeAddress
);
console.log({ response });
return response.results;
} catch (error) {
console.warn('Error fetching collectables');
Expand Down Expand Up @@ -214,6 +216,14 @@ onMounted(async () => {
isLoading.value = true;
safes.value = await createOsnapEnabledSafes();
newPluginData.value.safe = safes.value[0];
tokens.value = await fetchBalances(
newPluginData.value.safe.network,
newPluginData.value.safe.safeAddress
);
collectables.value = await fetchCollectibles(
newPluginData.value.safe.network,
newPluginData.value.safe.safeAddress
);
update(newPluginData.value);
isLoading.value = false;
});
Expand Down
21 changes: 21 additions & 0 deletions src/plugins/oSnap/components/HandleOutcome/HandleOutcome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getProposalExecutionDetails,
submitProposal
} from '../../utils';
import AssertionFailedInOO from './steps/AssertionFailedInOO.vue';
import AssertionPassedInOO from './steps/AssertionPassedInOO.vue';
import InOOChallengePeriod from './steps/InOOChallengePeriod.vue';
import ReadyForOOAssertion from './steps/ReadyForOOAssertion.vue';
Expand Down Expand Up @@ -51,6 +52,7 @@ type ProposalExecutionStep =
| 'ready-for-oo-assertion'
| 'in-oo-challenge-period'
| 'assertion-passed-in-oo'
| 'assertion-failed-in-oo'
| 'transactions-executed';
const isLoading = ref(true);
Expand Down Expand Up @@ -79,6 +81,14 @@ const proposalExecutionStep = computed<ProposalExecutionStep | undefined>(
if (assertionEvent && !assertionEvent.isExpired)
return 'in-oo-challenge-period';
if (
assertionEvent &&
assertionEvent.isExpired &&
assertionEvent.isSettled &&
assertionEvent.rejectedByOracle
)
return 'assertion-failed-in-oo';
if (assertionEvent && assertionEvent.isExpired && !assertionEvent.isSettled)
return 'assertion-passed-in-oo';
Expand Down Expand Up @@ -328,6 +338,17 @@ onMounted(async () => {
"
:log-index="proposalExecutionDetails.assertionEvent.logIndex"
/>
<AssertionFailedInOO
v-if="
proposalExecutionStep === 'assertion-failed-in-oo' &&
!!proposalExecutionDetails.assertionEvent
"
:network="network"
:proposal-tx-hash="
proposalExecutionDetails.assertionEvent.proposalTxHash
"
:log-index="proposalExecutionDetails.assertionEvent.logIndex"
/>
<AssertionPassedInOO
v-if="proposalExecutionStep === 'assertion-passed-in-oo'"
:transaction-count="transactions.length"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { getOracleUiLink } from '@/plugins/oSnap/utils';
import { type Network } from '../../../types';
const props = defineProps<{
network: Network;
proposalTxHash: string;
logIndex: number | string;
}>();
const oracleUiLink = getOracleUiLink(
props.network,
props.proposalTxHash,
Number(props.logIndex)
);
</script>

<template>
<span>
Proposal cannot be executed because it was disputed in the Oracle and failed
to pass the vote.
</span>

<div>
<a :href="oracleUiLink" rel="noreferrer noopener" target="_blank">
UMA Oracle URL
<span class="iconfont iconexternal-link" />
</a>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
<script setup lang="ts">
import { getOracleUiLink } from '@/plugins/oSnap/utils';
import { BigNumber } from '@ethersproject/bignumber';
import { type Network } from '../../../types';
const props = defineProps<{
network: Network;
expirationTimestamp: BigNumber;
proposalTxHash: string;
logIndex: number;
logIndex: number | string;
}>();
const oracleUiLink = getOracleUiLink(
props.network,
props.proposalTxHash,
props.logIndex
Number(props.logIndex)
);
const expirationDateLocaleString = new Date(
props.expirationTimestamp.toNumber() * 1000
).toLocaleString();
function getOracleUiLink(chain: string, txHash: string, logIndex: number) {
if (Number(chain) !== 5 && Number(chain) !== 80001) {
return `https://oracle.uma.xyz?transactionHash=${txHash}&eventIndex=${logIndex}`;
}
return `https://testnet.oracle.uma.xyz?transactionHash=${txHash}&eventIndex=${logIndex}`;
}
</script>

<template>
Expand Down
51 changes: 49 additions & 2 deletions src/plugins/oSnap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,60 @@ export type OsnapModelValue = {
oSnap: OsnapPluginData;
}

/**
* Represents the data associated with an assertion as defined in the OO V3 contract.
*
* In the contract definition, this is the `Assertion` struct.
*
* We don't represent the escalation manager settings because we don't need that in this app.
*
* struct Assertion {
EscalationManagerSettings escalationManagerSettings; // Settings related to the escalation manager.
address asserter; // Address of the asserter.
uint64 assertionTime; // Time of the assertion.
bool settled; // True if the request is settled.
IERC20 currency; // ERC20 token used to pay rewards and fees.
uint64 expirationTime; // Unix timestamp marking threshold when the assertion can no longer be disputed.
bool settlementResolution; // Resolution of the assertion (false till resolved).
bytes32 domainId; // Optional domain that can be used to relate the assertion to others in the escalationManager.
bytes32 identifier; // UMA DVM identifier to use for price requests in the event of a dispute.
uint256 bond; // Amount of currency that the asserter has bonded.
address callbackRecipient; // Address that receives the callback.
address disputer; // Address of the disputer.
}
*/
export type Assertion = {
asserter: string
assertionTime: BigNumber;
settled: boolean;
currency: string;
expirationTime: BigNumber;
settlementResolution: boolean;
domainId: string;
identifier: string;
bond: BigNumber;
callbackRecipient: string;
disputer: string;
}

export type AssertionGql = {
assertionId: string;
expirationTime: string;
assertionHash: string;
assertionLogIndex: string;
settlementHash: string | null;
settlementResolution: boolean | null;
}

export type AssertionEvent = {
assertionId: string;
proposalHash: string;
proposalTxHash: string;
logIndex: number;
logIndex: number | string;
expirationTimestamp: BigNumber;
isExpired: boolean;
isSettled: boolean;
rejectedByOracle: boolean;
}

/**
Expand Down Expand Up @@ -284,4 +330,5 @@ export type ProposalDetails = {
export type ProposalExecutionDetails = ProposalDetails & {
proposalId: string;
explanation: string;
}
}

26 changes: 19 additions & 7 deletions src/plugins/oSnap/utils/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
contractData,
safePrefixes
} from '../constants';
import { AssertionEvent, BalanceResponse, NFT, Network, OptimisticGovernorTransaction, ProposalDetails, ProposalExecutionDetails, SafeNetworkPrefix } from '../types';
import { Assertion, AssertionEvent, AssertionGql, BalanceResponse, NFT, Network, OptimisticGovernorTransaction, ProposalDetails, ProposalExecutionDetails, SafeNetworkPrefix } from '../types';
import { pageEvents } from './events';

/**
Expand Down Expand Up @@ -246,10 +246,14 @@ async function findAssertionGql(network: Network,
assertionHash
assertionLogIndex
settlementHash
settlementResolution
}
}
`;
const result = await queryGql(oracleUrl, request);
type Result = {
assertion: AssertionGql | undefined;
}
const result = await queryGql<Result>(oracleUrl, request);
return result?.assertion;
}
/**
Expand Down Expand Up @@ -468,14 +472,12 @@ export async function getProposalDetailsFromChain(provider: StaticJsonRpcProvide
// Get the full proposal events (with state).
const fullAssertionEvent = await Promise.all(
thisModuleAssertionEvent.map(async (event) => {
const assertion: {
expirationTime: BigNumber;
settled: boolean;
} = await oracleContract.getAssertion(
const assertion: Assertion = await oracleContract.getAssertion(
event.args?.assertionId
);

const isExpired = Math.floor(Date.now() / 1000) >= assertion.expirationTime.toNumber();
const rejectedByOracle = assertion.settled && !assertion.settlementResolution;

return {
assertionId: event?.args?.assertionId,
Expand All @@ -484,7 +486,8 @@ export async function getProposalDetailsFromChain(provider: StaticJsonRpcProvide
isSettled: assertion.settled,
proposalHash: proposalHash,
proposalTxHash: event.transactionHash,
logIndex: event.logIndex
logIndex: event.logIndex,
rejectedByOracle,
} as AssertionEvent;
})
);
Expand Down Expand Up @@ -586,6 +589,7 @@ export async function getProposalDetailsGql(provider: StaticJsonRpcProvider,
activeProposal: false,
assertionEvent: undefined,
proposalExecuted: false,
rejectedByOracle: false,
livenessPeriod: livenessPeriod
};
}
Expand All @@ -612,6 +616,7 @@ export async function getProposalDetailsGql(provider: StaticJsonRpcProvider,
expirationTimestamp: BigNumber.from(assertion.expirationTime),
isExpired: Math.floor(Date.now() / 1000) >= Number(assertion.expirationTime),
isSettled: assertion.settlementHash ? true : false,
rejectedByOracle: !!assertion.settlementHash && !assertion.settlementResolution,
proposalHash,
proposalTxHash: assertion.assertionHash,
logIndex: assertion.assertionLogIndex
Expand Down Expand Up @@ -709,4 +714,11 @@ export function getSafeNetworkPrefix(network: Network): SafeNetworkPrefix {
export function getSafeAppLink(network: Network, safeAddress: string, appUrl = "https://gnosis-safe.io/app/") {
const prefix = getSafeNetworkPrefix(network);
return `${appUrl}${prefix}:${safeAddress}`;
}

export function getOracleUiLink(chain: string, txHash: string, logIndex: number) {
if (Number(chain) !== 5 && Number(chain) !== 80001) {
return `https://oracle.uma.xyz?transactionHash=${txHash}&eventIndex=${logIndex}`;
}
return `https://testnet.oracle.uma.xyz?transactionHash=${txHash}&eventIndex=${logIndex}`;
}

0 comments on commit 5c91513

Please sign in to comment.