/
_helpers.js
110 lines (100 loc) · 2.76 KB
/
_helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
const { ethers } = require('hardhat')
const { networks } = require('@unlock-protocol/networks')
const { getNetwork } = require('@unlock-protocol/hardhat-helpers')
const multisigOldABI = require('@unlock-protocol/hardhat-helpers/dist/ABIs/multisig.json')
// get the correct provider if chainId is specified
const getProvider = async (chainId) => {
let provider
if (chainId) {
const { publicProvider } = networks[chainId]
provider = new ethers.JsonRpcProvider(publicProvider)
} else {
;({ provider } = ethers)
;({ chainId } = await getNetwork())
}
return { provider, chainId }
}
// custom services URL for network not supported by Safe
const safeServiceURLs = {
324: 'https://safe-transaction-zksync.safe.global/api',
1101: 'https://safe-transaction-zkevm.safe.global/api',
534352: 'https://transaction.safe.scroll.xyz/api',
59144: 'https://safe.linea.build/api',
}
// get safeAddress directly from unlock if needed
const getSafeAddress = async (chainId) => {
const { multisig } = networks[chainId]
return multisig
}
const getSafeVersion = async (safeAddress) => {
const abi = [
{
inputs: [],
name: 'VERSION',
outputs: [
{
internalType: 'string',
name: '',
type: 'string',
},
],
stateMutability: 'view',
type: 'function',
},
]
const safe = await ethers.getContractAt(abi, safeAddress)
try {
const version = await safe.VERSION()
return version
} catch (error) {
return 'old'
}
}
// mainnet still uses older versions of the safe
const submitTxOldMultisig = async ({ safeAddress, tx, signer }) => {
// encode contract call
const {
contractNameOrAbi,
contractAddress,
functionName,
functionArgs,
calldata,
value, // in ETH
} = tx
let encodedFunctionCall
if (!calldata) {
const { interface } = await ethers.getContractFactory(contractNameOrAbi)
encodedFunctionCall = interface.encodeFunctionData(
functionName,
functionArgs
)
} else {
encodedFunctionCall = calldata
}
console.log(
`Submitting ${functionName} to multisig ${safeAddress} (v: old)...`
)
const safe = new ethers.Contract(safeAddress, multisigOldABI, signer)
const txSubmitted = await safe.submitTransaction(
contractAddress,
value || 0, // ETH value
encodedFunctionCall
)
// submit to multisig
const receipt = await txSubmitted.wait()
const { transactionHash, events } = receipt
const nonce = events
.find(({ event }) => event === 'Submission')
.args.transactionId.toNumber()
console.log(
`Tx submitted to multisig with id '${nonce}' (txid: ${transactionHash})`
)
return nonce
}
module.exports = {
getProvider,
getSafeAddress,
getSafeVersion,
submitTxOldMultisig,
safeServiceURLs,
}