@exodus/ethereum-api 9.0.0-alpha.3 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2139 -0
- package/LICENSE +7 -0
- package/README.md +124 -0
- package/package.json +34 -33
- package/src/address-has-history.js +6 -2
- package/src/allowance/constants.js +4 -5
- package/src/allowance/index.js +159 -40
- package/src/check-tx/create-assess-transaction.js +23 -0
- package/src/check-tx/create-check-tx.js +104 -0
- package/src/check-tx/index.js +1 -0
- package/src/create-asset-plugin-factory.js +115 -0
- package/src/create-asset-utils.js +520 -0
- package/src/create-asset.js +273 -97
- package/src/create-token-factory.js +47 -17
- package/src/custom-fees.js +57 -0
- package/src/eip7702-whitelist.js +62 -0
- package/src/ens/index.js +12 -17
- package/src/error-wrapper.js +383 -0
- package/src/eth-like-util.js +172 -33
- package/src/exodus-eth-server/api-coin-nodes.js +27 -196
- package/src/exodus-eth-server/api.js +23 -14
- package/src/exodus-eth-server/clarity-v2.js +255 -0
- package/src/exodus-eth-server/clarity.js +67 -265
- package/src/exodus-eth-server/errors.js +40 -0
- package/src/exodus-eth-server/eth-like-server.js +385 -0
- package/src/exodus-eth-server/fetch-json.js +48 -0
- package/src/exodus-eth-server/index.js +77 -0
- package/src/exodus-eth-server/utils.js +31 -0
- package/src/exodus-eth-server/ws-gateway.js +306 -0
- package/src/exodus-eth-server/ws.js +1 -2
- package/src/fee-data/EthLikeFeeData.js +81 -0
- package/src/fee-data/index.js +54 -0
- package/src/fee-utils.js +229 -0
- package/src/gas-estimation.js +183 -66
- package/src/get-balance-for-address.js +1 -1
- package/src/get-balances.js +285 -27
- package/src/get-fee.js +92 -56
- package/src/get-historical-balance.js +58 -0
- package/src/hooks/index.js +1 -1
- package/src/hooks/monitor.js +182 -43
- package/src/hooks/staking-freshness.js +58 -0
- package/src/index.js +118 -12
- package/src/move-funds.js +153 -0
- package/src/multicall3/index.js +212 -0
- package/src/multisig-address.js +146 -0
- package/src/nft-utils.js +60 -0
- package/src/number-utils.js +34 -2
- package/src/optimism-gas/index.js +13 -5
- package/src/send-validations.js +58 -0
- package/src/server-based-fee-monitor.js +12 -19
- package/src/simulate-tx/fetch-tx-preview.js +0 -2
- package/src/simulate-tx/index.js +2 -2
- package/src/simulate-tx/simulate-eth-tx.js +24 -11
- package/src/simulation/common.js +34 -0
- package/src/simulation/create-simulate-message.js +49 -0
- package/src/simulation/create-simulate-transactions.js +108 -0
- package/src/simulation/estimate-fee.js +14 -0
- package/src/simulation/estimate-simple-transfer.js +15 -0
- package/src/simulation/get-message-type.js +18 -0
- package/src/simulation/simulate-message-api.js +68 -0
- package/src/simulation/simulate-transactions-api.js +266 -0
- package/src/simulation/simulate-transactions.js +16 -0
- package/src/simulation/transactions.js +52 -0
- package/src/simulation/try-estimating-changes-locally.js +26 -0
- package/src/staking/api/index.js +43 -0
- package/src/staking/cached-read.js +33 -0
- package/src/staking/ethereum/api.js +166 -34
- package/src/staking/ethereum/deps.js +37 -0
- package/src/staking/ethereum/everstake.js +113 -0
- package/src/staking/ethereum/index.js +4 -3
- package/src/staking/ethereum/service.js +682 -181
- package/src/staking/ethereum/staking-utils.js +275 -4
- package/src/staking/fantom-staking.js +9 -9
- package/src/staking/index.js +4 -4
- package/src/staking/matic/addresses.js +2 -0
- package/src/staking/matic/api.js +69 -49
- package/src/staking/matic/index.js +3 -3
- package/src/staking/matic/matic-staking-utils.js +243 -5
- package/src/staking/matic/matic-staking.md +53 -0
- package/src/staking/staking-provider-client.js +1 -1
- package/src/staking/utils/index.js +39 -0
- package/src/tx-create.js +666 -0
- package/src/tx-log/clarity-monitor.js +276 -103
- package/src/tx-log/clarity-truncated-history-monitor.js +130 -0
- package/src/tx-log/clarity-truncated-history-monitor.md +219 -0
- package/src/tx-log/clarity-utils/absolute.js +96 -0
- package/src/tx-log/clarity-utils/get-log-items-from-server-tx.js +94 -31
- package/src/tx-log/clarity-utils/get-names-of-tokens-transferred-by-server-tx.js +3 -2
- package/src/tx-log/clarity-utils/index.js +9 -3
- package/src/tx-log/clarity-utils/is-spam-pending-tx.js +13 -0
- package/src/tx-log/clarity-utils/normalize-transactions-response.js +65 -0
- package/src/tx-log/ethereum-monitor.js +93 -47
- package/src/tx-log/ethereum-no-history-monitor.js +52 -41
- package/src/tx-log/get-optimistic-txlog-effects.js +379 -0
- package/src/tx-log/index.js +5 -3
- package/src/tx-log/monitor-utils/check-pending-transactions.js +14 -5
- package/src/tx-log/monitor-utils/exclude-unchanged-token-balances.js +1 -1
- package/src/tx-log/monitor-utils/extract-balance-from-clarity-account-info.js +108 -0
- package/src/tx-log/monitor-utils/get-balance-updates.js +44 -0
- package/src/tx-log/monitor-utils/get-batched-rpc-balances.js +47 -0
- package/src/tx-log/monitor-utils/get-current-blacklist-status.js +38 -0
- package/src/tx-log/monitor-utils/get-current-eip7702-delegation.js +79 -0
- package/src/tx-log/monitor-utils/get-derive-transactions-to-check.js +10 -5
- package/src/tx-log/monitor-utils/get-fee-amount.js +1 -1
- package/src/tx-log/monitor-utils/get-history-from-server.js +1 -1
- package/src/tx-log/monitor-utils/get-log-items-from-server-tx.js +75 -33
- package/src/tx-log/monitor-utils/get-names-of-tokens-transferred-by-server-tx.js +3 -2
- package/src/tx-log/monitor-utils/get-raw-transfer-amount.js +29 -0
- package/src/tx-log/monitor-utils/get-transfers-by-token-name.js +3 -2
- package/src/tx-log/monitor-utils/get-value-of-transfers.js +10 -12
- package/src/tx-log/monitor-utils/index.js +12 -7
- package/src/tx-log/monitor-utils/is-unverifiable-pending-tx-expired.js +19 -0
- package/src/tx-log/monitor-utils/verify-pending-tx-status-rpc.js +90 -0
- package/src/tx-log-staking-processor/asset-staking-tx-data.js +82 -24
- package/src/tx-log-staking-processor/index.js +28 -14
- package/src/tx-log-staking-processor/utils.js +21 -20
- package/src/tx-send/broadcast-error-handler.js +63 -0
- package/src/tx-send/index.js +1 -2
- package/src/tx-send/nonce-utils.js +97 -0
- package/src/tx-send/tx-send.js +94 -288
- package/src/tx-sign/index.js +17 -0
- package/src/tx-type/index.js +280 -0
- package/src/watch-tx.js +36 -0
- package/src/web3/createSimulateMessage.js +3 -2
- package/src/web3/createSimulateTransactions.js +11 -0
- package/src/web3/index.js +3 -1
- package/src/etherscan/account.js +0 -49
- package/src/etherscan/index.js +0 -28
- package/src/etherscan/logs.js +0 -16
- package/src/etherscan/proxy.js +0 -47
- package/src/etherscan/request.js +0 -26
- package/src/etherscan/ws.js +0 -88
- package/src/exodus-eth-server/server-factory.js +0 -28
- package/src/exodus-eth-server/server-map.js +0 -21
- package/src/get-fee-async.js +0 -97
- package/src/staking/matic/service.js +0 -437
- package/src/staking-api.js +0 -5
- package/src/tx-log/clarity-utils/get-derive-data-needed-for-tick.js +0 -12
- package/src/tx-log-staking-processor/get-asset-tx-amount.js +0 -26
- package/src/tx-send/get-fee-info.js +0 -41
- package/src/websocket/index.android.js +0 -2
- package/src/websocket/index.ios.js +0 -2
- package/src/websocket/index.js +0 -21
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import NumberUnit from '@exodus/currency'
|
|
2
|
+
import { getMethodIdFromEthTx, isPendingTxInLog, parseUnsignedTx } from '@exodus/ethereum-lib'
|
|
3
|
+
import assetsList, { asset as ethereum } from '@exodus/ethereum-meta'
|
|
4
|
+
import { Tx } from '@exodus/models'
|
|
5
|
+
import assert from 'minimalistic-assert'
|
|
6
|
+
|
|
7
|
+
import { simulateTransactions as simulateEthereumTransactions } from '../../simulation/simulate-transactions.js'
|
|
8
|
+
import { decodePolygonStakingTxInputAmount } from '../../tx-log-staking-processor/utils.js'
|
|
9
|
+
import { MaticStakingApi } from './api.js'
|
|
2
10
|
|
|
3
11
|
// function selector for buyVoucher(uint256 _amount, uint256 _minSharesToMint)
|
|
4
|
-
const DELEGATE = '0x6ab15071'
|
|
12
|
+
export const DELEGATE = '0x6ab15071'
|
|
5
13
|
// function selector for sellVoucher_new(uint256 claimAmount, uint256 maximumSharesToBurn)
|
|
6
14
|
const UNDELEGATE = '0xc83ec04d'
|
|
7
15
|
// function selector for withdrawRewards()
|
|
@@ -11,14 +19,244 @@ const CLAIM_UNDELEGATE_BALANCE = '0xe97fddc2'
|
|
|
11
19
|
|
|
12
20
|
const STAKING_MANAGER_CONTRACT = MaticStakingApi.STAKING_MANAGER_ADDR
|
|
13
21
|
|
|
22
|
+
const METHOD_ID_CHAR_LENGTH = 10
|
|
23
|
+
|
|
24
|
+
const { currency: polygonCurrency } = assetsList.find(
|
|
25
|
+
({ name: tokenName }) => tokenName === 'polygon'
|
|
26
|
+
)
|
|
27
|
+
const currencies = { ethereum: ethereum.currency, polygon: polygonCurrency }
|
|
28
|
+
|
|
14
29
|
export const isPolygonTx = ({ coinName }) => coinName === 'polygon'
|
|
15
30
|
export const isPolygonDelegate = (tx) =>
|
|
16
31
|
isPolygonTx(tx) && tx.to === STAKING_MANAGER_CONTRACT && tx.data?.methodId === DELEGATE
|
|
17
32
|
export const isPolygonUndelegate = (tx) =>
|
|
18
|
-
isPolygonTx(tx) && tx.from[0] === STAKING_MANAGER_CONTRACT && tx.data?.methodId === UNDELEGATE
|
|
33
|
+
isPolygonTx(tx) && tx.from?.[0] === STAKING_MANAGER_CONTRACT && tx.data?.methodId === UNDELEGATE
|
|
19
34
|
export const isPolygonReward = (tx) =>
|
|
20
|
-
isPolygonTx(tx) && tx.from[0] === STAKING_MANAGER_CONTRACT && tx.data?.methodId === CLAIM_REWARD
|
|
35
|
+
isPolygonTx(tx) && tx.from?.[0] === STAKING_MANAGER_CONTRACT && tx.data?.methodId === CLAIM_REWARD
|
|
21
36
|
export const isPolygonClaimUndelegate = (tx) =>
|
|
22
37
|
isPolygonTx(tx) &&
|
|
23
|
-
tx.from[0] === STAKING_MANAGER_CONTRACT &&
|
|
38
|
+
tx.from?.[0] === STAKING_MANAGER_CONTRACT &&
|
|
24
39
|
tx.data?.methodId === CLAIM_UNDELEGATE_BALANCE
|
|
40
|
+
|
|
41
|
+
const isPolygonStakingContractTxInEthereumTxLog = (tx) =>
|
|
42
|
+
tx.to === MaticStakingApi.EVERSTAKE_VALIDATOR_CONTRACT_ADDR
|
|
43
|
+
|
|
44
|
+
const isPolygonStakingContractCallInEthTx = ({ tx, methodId }) =>
|
|
45
|
+
tx?.data?.data?.slice?.(0, Math.max(0, METHOD_ID_CHAR_LENGTH)) === methodId // ETH txs have contract data in 'data'
|
|
46
|
+
|
|
47
|
+
const isPolygonUndelegateTxInEthreumTxLog = (tx) =>
|
|
48
|
+
isPolygonStakingContractCallInEthTx({ tx, methodId: UNDELEGATE })
|
|
49
|
+
|
|
50
|
+
// Some polygon unstake txs are only kept in the ETH tx log rather than Polygon tx log.
|
|
51
|
+
// This is b/c the given tx does not have any ERC2O token transfer (MATIC).
|
|
52
|
+
// Token tx log only has txs which contains ERC2O token transfer of the given token.
|
|
53
|
+
export const isPolygonUndelegateTxInEthereumTxLog = (tx) =>
|
|
54
|
+
isPolygonStakingContractTxInEthereumTxLog(tx) && isPolygonUndelegateTxInEthreumTxLog(tx)
|
|
55
|
+
|
|
56
|
+
// Pending variant intended for client-side selectors (e.g. "show Unstaking… as
|
|
57
|
+
// soon as the tx hits the log"). Composes the shared tx-log lifecycle and
|
|
58
|
+
// method-ID helpers so this and the asset-side preflight in
|
|
59
|
+
// @exodus/ethereum-plugin/staking/polygon/staking-utils agree on what "pending"
|
|
60
|
+
// means from a single definition.
|
|
61
|
+
export const isPendingPolygonUndelegateTxInEthereumTxLog = (tx) =>
|
|
62
|
+
!!tx &&
|
|
63
|
+
isPendingTxInLog(tx) &&
|
|
64
|
+
tx.to?.toLowerCase() === MaticStakingApi.EVERSTAKE_VALIDATOR_CONTRACT_ADDR &&
|
|
65
|
+
getMethodIdFromEthTx(tx, UNDELEGATE) === UNDELEGATE
|
|
66
|
+
|
|
67
|
+
export const createUndelegateTx = (tx) => {
|
|
68
|
+
return Tx.fromJSON({
|
|
69
|
+
...tx,
|
|
70
|
+
coinName: 'polygon',
|
|
71
|
+
coinAmount: currencies.polygon.ZERO,
|
|
72
|
+
tokens: [],
|
|
73
|
+
currencies,
|
|
74
|
+
from: [STAKING_MANAGER_CONTRACT],
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const getPolygonUndelegateTxInEthereumTxLog = (ethereumLogItems) => {
|
|
79
|
+
if (!ethereumLogItems || ethereumLogItems.length === 0) return []
|
|
80
|
+
|
|
81
|
+
const polygonLogItems = []
|
|
82
|
+
const polygonEthUndelegateTxs = [...ethereumLogItems].filter((tx) =>
|
|
83
|
+
isPolygonUndelegateTxInEthereumTxLog(tx)
|
|
84
|
+
)
|
|
85
|
+
const polygonUndelegateTxs = [...polygonEthUndelegateTxs].map((tx) => createUndelegateTx(tx))
|
|
86
|
+
|
|
87
|
+
for (const polygonTx of polygonUndelegateTxs) {
|
|
88
|
+
polygonLogItems.push(polygonTx)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
polygonLogItems.sort((a, b) => new Date(b.date) - new Date(a.date))
|
|
92
|
+
|
|
93
|
+
return polygonLogItems
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Build simulation transaction requests from unsigned transactions
|
|
97
|
+
export function createMaticStakeSimRequestsFromUnsigned({
|
|
98
|
+
asset,
|
|
99
|
+
unsignedTxApprove,
|
|
100
|
+
unsignedTxDelegate,
|
|
101
|
+
}) {
|
|
102
|
+
const build = (tx) => {
|
|
103
|
+
const parsed = parseUnsignedTx({ asset, unsignedTx: tx.unsignedTx })
|
|
104
|
+
const gasPriceUnit = tx.gasPrice
|
|
105
|
+
const chainId = tx.unsignedTx?.txData?.chainId
|
|
106
|
+
const from = tx.unsignedTx?.txMeta?.fromAddress
|
|
107
|
+
const to = tx.unsignedTx?.txMeta?.toAddress
|
|
108
|
+
|
|
109
|
+
assert(gasPriceUnit instanceof NumberUnit, 'expected NumberUnit gasPrice')
|
|
110
|
+
assert(Number.isInteger(chainId), 'expected integer chainId')
|
|
111
|
+
assert(typeof from === 'string' && from, 'expected string fromAddress')
|
|
112
|
+
assert(typeof to === 'string' && to, 'expected string toAddress')
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
chainId,
|
|
116
|
+
from,
|
|
117
|
+
to,
|
|
118
|
+
gas: `0x${parsed.gasLimit.toString(16)}`,
|
|
119
|
+
gasPrice: `0x${BigInt(gasPriceUnit.toBaseString()).toString(16)}`,
|
|
120
|
+
value: '0x0',
|
|
121
|
+
data: `0x${parsed.data?.toString('hex')}`,
|
|
122
|
+
nonce: `0x${parsed.nonce.toString(16)}`,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
approveTxRequest: build(unsignedTxApprove),
|
|
128
|
+
delegateTxRequest: build(unsignedTxDelegate),
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function maticDelegateOptimisticSideEffectTxLogs({
|
|
133
|
+
asset, // Base asset
|
|
134
|
+
walletAccount,
|
|
135
|
+
feeAmount,
|
|
136
|
+
delegateTxId,
|
|
137
|
+
nonce,
|
|
138
|
+
estimatedDelegateGasLimit,
|
|
139
|
+
tipGasPrice,
|
|
140
|
+
transactionData,
|
|
141
|
+
date,
|
|
142
|
+
bundleId,
|
|
143
|
+
}) {
|
|
144
|
+
// Decode the amount from the delegate transaction data
|
|
145
|
+
// transactionData is already parsed from unsignedTx using parseUnsignedTx
|
|
146
|
+
let amount
|
|
147
|
+
try {
|
|
148
|
+
// Decode the contract call data - buyVoucher(uint256 _amount, uint256 _minSharesToMint)
|
|
149
|
+
const decodedAmount = decodePolygonStakingTxInputAmount({ data: { data: transactionData } })
|
|
150
|
+
// Convert to NumberUnit - the decoded amount is a string like '100000000'
|
|
151
|
+
amount = polygonCurrency.baseUnit(decodedAmount)
|
|
152
|
+
} catch (e) {
|
|
153
|
+
console.error(
|
|
154
|
+
'Could not decode MATIC delegate transaction data:',
|
|
155
|
+
delegateTxId,
|
|
156
|
+
e.message,
|
|
157
|
+
transactionData
|
|
158
|
+
)
|
|
159
|
+
return [] // Could not decode the amount
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const tokenAssetName = 'polygon'
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
assetName: tokenAssetName,
|
|
166
|
+
walletAccount,
|
|
167
|
+
txs: [
|
|
168
|
+
{
|
|
169
|
+
confirmations: 0,
|
|
170
|
+
feeAmount,
|
|
171
|
+
feeCoinName: asset.feeAsset.name,
|
|
172
|
+
selfSend: false,
|
|
173
|
+
to: MaticStakingApi.EVERSTAKE_VALIDATOR_CONTRACT_ADDR,
|
|
174
|
+
txId: delegateTxId,
|
|
175
|
+
data: {
|
|
176
|
+
gasLimit: estimatedDelegateGasLimit,
|
|
177
|
+
nonce,
|
|
178
|
+
tipGasPrice: tipGasPrice ? tipGasPrice.toBaseString() : undefined,
|
|
179
|
+
methodId: DELEGATE,
|
|
180
|
+
...(bundleId ? { bundleId } : null),
|
|
181
|
+
},
|
|
182
|
+
coinAmount: amount.abs().negate(),
|
|
183
|
+
coinName: tokenAssetName,
|
|
184
|
+
currencies: {
|
|
185
|
+
[tokenAssetName]: polygonCurrency,
|
|
186
|
+
[asset.feeAsset.name]: asset.feeAsset.currency,
|
|
187
|
+
},
|
|
188
|
+
date,
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export async function maticDelegateSimulateTransactions({
|
|
196
|
+
asset,
|
|
197
|
+
unsignedTxApprove,
|
|
198
|
+
unsignedTxDelegate,
|
|
199
|
+
senderAddress,
|
|
200
|
+
revertOnSimulationError,
|
|
201
|
+
}) {
|
|
202
|
+
const { approveTxRequest, delegateTxRequest } = createMaticStakeSimRequestsFromUnsigned({
|
|
203
|
+
asset: asset.baseAsset,
|
|
204
|
+
unsignedTxApprove,
|
|
205
|
+
unsignedTxDelegate,
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
// Simulate transactions
|
|
209
|
+
const simulationTxData = {
|
|
210
|
+
baseAssetName: asset.baseAsset.name,
|
|
211
|
+
origin: 'exodus-staking',
|
|
212
|
+
senderAddress,
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const simulationResponse = await simulateEthereumTransactions({
|
|
216
|
+
asset: asset.baseAsset,
|
|
217
|
+
...simulationTxData,
|
|
218
|
+
transactions: [approveTxRequest, delegateTxRequest],
|
|
219
|
+
})
|
|
220
|
+
// These checks are only for simulation issues, not validation of the transactions
|
|
221
|
+
if (simulationResponse?.warnings?.length || simulationResponse?.metadata?.humanReadableError) {
|
|
222
|
+
if (revertOnSimulationError) {
|
|
223
|
+
const err = new Error('StakingMaticSimulationError')
|
|
224
|
+
err.message = simulationResponse?.metadata?.humanReadableError
|
|
225
|
+
err.reason = `warnings: ${simulationResponse.warnings.join(', ')}`
|
|
226
|
+
err.hint = 'delegate-matic-simulation-error'
|
|
227
|
+
throw err
|
|
228
|
+
} else {
|
|
229
|
+
console.warn(
|
|
230
|
+
'Simulation for staking matic returned issues',
|
|
231
|
+
simulationResponse?.metadata?.humanReadableError
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// For validation of the transactions, we need to check if the simulation produced the expected effects
|
|
237
|
+
// hasApprove, hasSend, hasReceive entries must be present
|
|
238
|
+
const { balanceChanges = Object.create(null) } = simulationResponse || Object.create(null)
|
|
239
|
+
const asArray = (v) => (Array.isArray(v) ? v : [])
|
|
240
|
+
const hasApprove = asArray(balanceChanges.willApprove).length > 0
|
|
241
|
+
const hasSend = asArray(balanceChanges.willSend).length > 0
|
|
242
|
+
const hasReceive = asArray(balanceChanges.willReceive).length > 0
|
|
243
|
+
|
|
244
|
+
if (!(hasApprove && hasSend && hasReceive)) {
|
|
245
|
+
if (revertOnSimulationError) {
|
|
246
|
+
const missing = []
|
|
247
|
+
if (!hasApprove) missing.push('willApprove')
|
|
248
|
+
if (!hasSend) missing.push('willSend')
|
|
249
|
+
if (!hasReceive) missing.push('willReceive')
|
|
250
|
+
const err = new Error('StakingMaticSimulationResultsError')
|
|
251
|
+
err.message = 'Simulation did not produce expected effects'
|
|
252
|
+
err.reason = `missing balanceChanges: ${missing.join(', ')}`
|
|
253
|
+
err.hint = 'delegate-matic-simulation-results-error'
|
|
254
|
+
throw err
|
|
255
|
+
} else {
|
|
256
|
+
console.warn(
|
|
257
|
+
'Simulation for staking matic returned issues',
|
|
258
|
+
simulationResponse?.metadata?.humanReadableError
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -13,6 +13,59 @@ Stakers are divided into `validators`, `delegators`, and watchers (for fraud rep
|
|
|
13
13
|
|
|
14
14
|
`StakeManager` is the main contract for handling validator related activities like checkPoint signature verification, reward distribution, and stake management. Since the contract is using NFT ID as a source of ownership, change of ownership and signer won't affect anything in the system. [see](https://wiki.polygon.technology/docs/pos/contracts/stakingmanager).
|
|
15
15
|
|
|
16
|
+
#### Storage Layout
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
| Name | Type | Slot | Offset | Bytes | Value | Hex Value | Contract |
|
|
20
|
+
|-----------------------------|------------------------------------------------------------|------|--------|-------|--------------------------------------------------|--------------------------------------------------------------------|--------------------------------------------------------------|
|
|
21
|
+
| locked | bool | 0 | 0 | 1 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
22
|
+
| governance | contract IGovernance | 0 | 1 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
23
|
+
| _owner | address | 1 | 0 | 20 | 289681683732047618769883796824487869827960101094 | 0x00000000000000000000000032bdc6a4e8c654df65503cbb0edc82b4ce9158e6 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
24
|
+
| rootChain | address | 2 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
25
|
+
| token | contract IERC20 | 3 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
26
|
+
| registry | address | 4 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
27
|
+
| logger | contract StakingInfo | 5 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
28
|
+
| NFTContract | contract StakingNFT | 6 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
29
|
+
| validatorShareFactory | contract ValidatorShareFactory | 7 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
30
|
+
| WITHDRAWAL_DELAY | uint256 | 8 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
31
|
+
| currentEpoch | uint256 | 9 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
32
|
+
| dynasty | uint256 | 10 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
33
|
+
| CHECKPOINT_REWARD | uint256 | 11 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
34
|
+
| minDeposit | uint256 | 12 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
35
|
+
| minHeimdallFee | uint256 | 13 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
36
|
+
| checkPointBlockInterval | uint256 | 14 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
37
|
+
| signerUpdateLimit | uint256 | 15 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
38
|
+
| validatorThreshold | uint256 | 16 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
39
|
+
| totalStaked | uint256 | 17 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
40
|
+
| NFTCounter | uint256 | 18 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
41
|
+
| totalRewards | uint256 | 19 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
42
|
+
| totalRewardsLiquidated | uint256 | 20 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
43
|
+
| auctionPeriod | uint256 | 21 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
44
|
+
| proposerBonus | uint256 | 22 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
45
|
+
| accountStateRoot | bytes32 | 23 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
46
|
+
| replacementCoolDown | uint256 | 24 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
47
|
+
| delegationEnabled | bool | 25 | 0 | 1 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
48
|
+
| validators | mapping(uint256 => struct StakeManagerStorage.Validator) | 26 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
49
|
+
| signerToValidator | mapping(address => uint256) | 27 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
50
|
+
| validatorState | struct StakeManagerStorage.State | 28 | 0 | 64 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
51
|
+
| validatorStateChanges | mapping(uint256 => struct StakeManagerStorage.StateChange) | 30 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
52
|
+
| userFeeExit | mapping(address => uint256) | 31 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
53
|
+
| validatorAuction | mapping(uint256 => struct StakeManagerStorage.Auction) | 32 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
54
|
+
| latestSignerUpdateEpoch | mapping(uint256 => uint256) | 33 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
55
|
+
| totalHeimdallFee | uint256 | 34 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
56
|
+
| inited | bool | 35 | 0 | 1 | 1 | 0x0000000000000000000000000000000000000000000000000000000000000001 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
57
|
+
| eventsHub | address | 35 | 1 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
58
|
+
| rewardPerStake | uint256 | 36 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
59
|
+
| extensionCode | address | 37 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
60
|
+
| signers | address[] | 38 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
61
|
+
| prevBlockInterval | uint256 | 39 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
62
|
+
| rewardDecreasePerCheckpoint | uint256 | 40 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
63
|
+
| maxRewardedCheckpoints | uint256 | 41 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
64
|
+
| checkpointRewardDelta | uint256 | 42 | 0 | 32 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
65
|
+
| tokenMatic | contract IERC20 | 43 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
66
|
+
| migration | contract IPolygonMigration | 44 | 0 | 20 | 0 | 0x0000000000000000000000000000000000000000000000000000000000000000 | contracts/staking/stakeManager/StakeManager.sol:StakeManager |
|
|
67
|
+
```
|
|
68
|
+
|
|
16
69
|
### ValidatorShare contract
|
|
17
70
|
|
|
18
71
|
For delegation staking each validator has its own deployed **contract**, this contract has the logic to `stake/unstake` as delegators, but it also acts as an `ERC20`, this `ERC20` token is what we know as the shares token. Shares token are calculated based on the total amount staked in the contract, varying from time to time
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isNumberUnit } from '@exodus/currency'
|
|
2
|
+
|
|
3
|
+
export const DISABLE_BALANCE_CHECKS = '0x0'
|
|
4
|
+
|
|
5
|
+
export function amountToCurrency({ asset, amount }) {
|
|
6
|
+
return isNumberUnit(amount) ? amount : asset.currency.parse(amount)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Previously, EVM staking services would determine `feeData`
|
|
11
|
+
* dynamically on behalf of callers, however, this risks invalidating
|
|
12
|
+
* fee estimation over the course of a sequence of multiple staking
|
|
13
|
+
* transactions.
|
|
14
|
+
*
|
|
15
|
+
* For example, when determining the amount for a `sendAll`
|
|
16
|
+
* transaction, if the gas price were to increase between estimation
|
|
17
|
+
* and execution, this would invalidate the previous estimation.
|
|
18
|
+
*
|
|
19
|
+
* In future usage, we would want assets code to fetch FeeData from ACI,
|
|
20
|
+
* construct a transaction including determining the fee and then report
|
|
21
|
+
* back to the client what the fee is going to be.
|
|
22
|
+
*
|
|
23
|
+
* Importantly, the provided `feeData` must be sufficiently
|
|
24
|
+
* up-to-date; else, we risk the transactions not being included at all.
|
|
25
|
+
*/
|
|
26
|
+
export const resolveFeeData = async ({
|
|
27
|
+
// TODO: maybe asset name would be better
|
|
28
|
+
asset,
|
|
29
|
+
assetClientInterface,
|
|
30
|
+
feeData,
|
|
31
|
+
}) => {
|
|
32
|
+
if (feeData) return feeData
|
|
33
|
+
|
|
34
|
+
console.warn(
|
|
35
|
+
'The evm staking service was not explicitly passed `feeData`. This can result in transaction nondeterminism.'
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return assetClientInterface.getFeeData({ assetName: asset.name })
|
|
39
|
+
}
|