Skip to content

Commit

Permalink
[SafeSnap] Multisend configuration (snapshot-labs#1490)
Browse files Browse the repository at this point in the history
* safesnap: display transaction hashes

* [safesnap] upload file WIP

* [safesnap] display correct native asset for all chains

* [safesnap] use symbol in transfer funds form

* [safesnap] import transaction from JSON file

* [safesnap] allow to set the multi-send contract address in safesnap conf

* [safesnap] move common functions to one file

* [safesnap] tooltip to display multisend & reality-module address

* [safesnap] move plugin logic to snapshot-plugins repo

* [safesnap] avoid hash calculation in preview view

* [safesnap] update execution progress

Co-authored-by: Fabien <[email protected]>
Co-authored-by: mkt <[email protected]>
  • Loading branch information
3 people authored Jan 26, 2022
1 parent 4e57d9a commit ac3c843
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 800 deletions.
24 changes: 9 additions & 15 deletions src/components/Plugin/SafeSnap/Config.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
<script>
import { clone } from '@snapshot-labs/snapshot.js/src/utils';
import { validateSafeData, getSafeHash } from '@/helpers/abi/utils';
const isValidInput = input => {
return input.safes.every(validateSafeData);
};
const coerceConfig = (config, network) => {
if (config.safes) return config;
// map legacy config to new format
return {
safes: [{ network, realityAddress: config.address }]
};
};
import {
coerceConfig,
isValidInput,
getSafeHash
} from '@/../snapshot-plugins/src/plugins/safeSnap';
export default {
props: [
Expand All @@ -34,7 +25,9 @@ export default {
valid: true
};
return {
input: this.modelValue ? clone(this.modelValue) : initialValue
input: this.modelValue
? coerceConfig(clone(this.modelValue), this.network)
: initialValue
};
},
methods: {
Expand Down Expand Up @@ -73,6 +66,7 @@ export default {
:hash="safe.hash"
:network="safe.network"
:realityAddress="safe.realityAddress"
:multiSendAddress="safe.multiSendAddress"
:modelValue="safe.txs"
@update:modelValue="updateSafeTransactions(index, $event)"
/>
Expand Down
26 changes: 14 additions & 12 deletions src/components/Plugin/SafeSnap/Form/ContractInteraction.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<script>
import Plugin from '@/../snapshot-plugins/src/plugins/safeSnap';
import {
import Plugin, {
contractInteractionToModuleTransaction,
getABIWriteFunctions,
getContractABI,
getContractTransactionData
} from '@/helpers/abi/utils';
getContractTransactionData,
InterfaceDecoder
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isBigNumberish } from '@ethersproject/bignumber/lib/bignumber';
import { isAddress } from '@ethersproject/address';
import { parseAmount } from '@/helpers/utils';
import { InterfaceDecoder } from '@/helpers/abi/decoder';
export default {
props: ['modelValue', 'nonce', 'config'],
Expand Down Expand Up @@ -113,13 +112,16 @@ export default {
this.parameters
);
const transaction = contractInteractionToModuleTransaction({
data,
to: this.to,
value: this.value,
nonce: this.nonce,
method: this.selectedMethod
});
const transaction = contractInteractionToModuleTransaction(
{
data,
to: this.to,
value: this.value,
nonce: this.nonce,
method: this.selectedMethod
},
this.config.multiSendAddress
);
if (this.plugin.validateTransaction(transaction)) {
this.$emit('update:modelValue', transaction);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import { getNativeAsset } from '@/helpers/abi/utils';
import { getNativeAsset } from '@/../snapshot-plugins/src/plugins/safeSnap';
import { parseEther } from '@ethersproject/units';
import { isAddress } from '@ethersproject/address';
import { FunctionFragment, Interface } from '@ethersproject/abi';
Expand Down
12 changes: 6 additions & 6 deletions src/components/Plugin/SafeSnap/Form/RawTransaction.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script>
import Plugin from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isHexString } from '@ethersproject/bytes';
import { parseAmount } from '@/helpers/utils';
import {
import Plugin, {
decodeTransactionData,
rawToModuleTransaction
} from '@/helpers/abi/utils';
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isHexString } from '@ethersproject/bytes';
import { parseAmount } from '@/helpers/utils';
export default {
props: ['modelValue', 'nonce', 'config'],
Expand All @@ -30,7 +29,8 @@ export default {
try {
const transaction = await decodeTransactionData(
this.config.network,
this.modelValue
this.modelValue,
this.config.multiSendAddress
);
if (this.plugin.validateTransaction(transaction)) {
this.$emit('update:modelValue', transaction);
Expand Down
7 changes: 3 additions & 4 deletions src/components/Plugin/SafeSnap/Form/SendAsset.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<script>
import Plugin from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isAddress } from '@ethersproject/address';
import {
import Plugin, {
getERC721TokenTransferTransactionData,
sendAssetToModuleTransaction
} from '@/helpers/abi/utils';
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isAddress } from '@ethersproject/address';
import { shorten } from '@/helpers/utils';
export default {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Plugin/SafeSnap/Form/Transaction.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import { formatUnits } from '@ethersproject/units';
import { getAbiFirstFunctionName } from '@/helpers/abi/utils';
import { getAbiFirstFunctionName } from '@/../snapshot-plugins/src/plugins/safeSnap';
import { shorten } from '@/helpers/utils';
const labels = {
Expand Down
28 changes: 19 additions & 9 deletions src/components/Plugin/SafeSnap/Form/TransactionBatch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { useSafesnap } from '@/composables/useSafesnap';
import chevronIcon from '@/assets/icons/chevron.svg';
import {
createBatch,
ERC20ContractABI,
ERC721ContractABI,
removeHexPrefix
} from '@/helpers/abi/utils';
ERC20_ABI,
ERC721_ABI
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import { formatEther } from '@ethersproject/units';
import { FunctionFragment, Interface } from '@ethersproject/abi';
Expand All @@ -16,7 +15,7 @@ export default {
emits: ['update:modelValue', 'remove'],
setup() {
const { safesnap } = useSafesnap();
return { safesnap, removeHexPrefix };
return { safesnap };
},
data() {
return {
Expand All @@ -39,6 +38,7 @@ export default {
this.transactions.push(undefined);
},
updateTransaction(index, transaction) {
if (this.config.preview) return;
this.transactions[index] = transaction;
this.updateBatch(this.transactions);
},
Expand All @@ -55,7 +55,13 @@ export default {
},
createBatch(nonce, txs) {
const chainId = parseInt(this.config.network);
return createBatch(this.config.realityAddress, chainId, nonce, txs);
return createBatch(
this.config.realityAddress,
chainId,
nonce,
txs,
this.config.multiSendAddress
);
},
formatBatchJson(txs) {
const valid = txs.every(tx => tx);
Expand All @@ -73,10 +79,10 @@ export default {
if (tx.data.length > 2) {
switch (tx.type) {
case 'transferFunds':
abi = ERC20ContractABI;
abi = ERC20_ABI;
break;
case 'transferNFT':
abi = ERC721ContractABI;
abi = ERC721_ABI;
break;
default:
base.data = tx.data;
Expand All @@ -85,8 +91,12 @@ export default {
}
if (abi) {
const signHash = tx.data.substr(0, 10);
const contractInterface = new Interface(abi);
const func = FunctionFragment.from(contractInterface.fragments[0]);
const functionFragment = contractInterface.fragments
.filter(frag => FunctionFragment.isFunctionFragment(frag))
.find(frag => contractInterface.getSighash(frag) === signHash);
const func = FunctionFragment.from(functionFragment);
const params = contractInterface.decodeFunctionData(func, tx.data);
return {
...base,
Expand Down
9 changes: 4 additions & 5 deletions src/components/Plugin/SafeSnap/Form/TransferFunds.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script>
import Plugin from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isBigNumberish } from '@ethersproject/bignumber/lib/bignumber';
import { isAddress } from '@ethersproject/address';
import {
import Plugin, {
getERC20TokenTransferTransactionData,
getNativeAsset,
transferFundsToModuleTransaction
} from '@/helpers/abi/utils';
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import { isBigNumberish } from '@ethersproject/bignumber/lib/bignumber';
import { isAddress } from '@ethersproject/address';
export default {
props: ['modelValue', 'nonce', 'config'],
Expand Down
23 changes: 18 additions & 5 deletions src/components/Plugin/SafeSnap/HandleOutcome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,13 @@
</template>

<script>
import Plugin from '@/../snapshot-plugins/src/plugins/safeSnap';
import Plugin, {
formatBatchTransaction
} from '@/../snapshot-plugins/src/plugins/safeSnap';
import networks from '@snapshot-labs/snapshot.js/src/networks.json';
import { getInstance } from '@snapshot-labs/lock/plugins/vue3';
import { sleep } from '@snapshot-labs/snapshot.js/src/utils';
import { BigNumber } from '@ethersproject/bignumber';
import { formatBatchTransaction } from '@/helpers/abi/utils';
import { formatUnits } from '@ethersproject/units';
import { useSafesnap } from '@/composables/useSafesnap';
import { useWeb3 } from '@/composables/useWeb3';
Expand Down Expand Up @@ -241,7 +242,13 @@ const ensureRightNetwork = async chainId => {
};
export default {
props: ['batches', 'proposalId', 'network', 'realityAddress'],
props: [
'batches',
'proposalId',
'network',
'realityAddress',
'multiSendAddress'
],
data() {
return {
loading: true,
Expand All @@ -261,15 +268,19 @@ export default {
},
methods: {
async updateDetails() {
if (!this.realityAddress) return;
if (!this.realityAddress || !this.multiSendAddress) return;
this.loading = true;
try {
this.questionDetails = await plugin.getExecutionDetails(
this.network,
this.realityAddress,
this.proposalId,
this.batches.map((batch, nonce) =>
formatBatchTransaction(batch.transactions, nonce)
formatBatchTransaction(
batch.transactions,
nonce,
this.multiSendAddress
)
)
);
if (this.questionDetails.questionId && this.$auth.web3) {
Expand Down Expand Up @@ -397,6 +408,8 @@ export default {
await executingProposal.next();
notify(this.$i18n.t('notify.youDidIt'));
pendingCount.value--;
await sleep(3e3);
await this.updateDetails();
} catch (err) {
pendingCount.value--;
this.action2InProgress = null;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Plugin/SafeSnap/Input/Address.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import { mustBeEthereumAddress } from '@/helpers/abi/utils';
import { mustBeEthereumAddress } from '@/../snapshot-plugins/src/plugins/safeSnap';
export default {
props: ['modelValue', 'inputProps', 'label', 'disabled'],
Expand Down
Loading

0 comments on commit ac3c843

Please sign in to comment.