Removing daily limit in logic
This commit is contained in:
parent
9b647a8e20
commit
451f3505a2
|
@ -1,48 +0,0 @@
|
||||||
// @flow
|
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
|
||||||
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/logic/contracts/safeContracts'
|
|
||||||
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
|
|
||||||
|
|
||||||
export const LIMIT_POSITION = 0
|
|
||||||
export const SPENT_TODAY_POS = 1
|
|
||||||
|
|
||||||
|
|
||||||
export const getDailyLimitModuleFrom = async (safeAddress: string) => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
const gnosisSafe = getGnosisSafeContract(web3).at(safeAddress)
|
|
||||||
|
|
||||||
const modules = await gnosisSafe.getModules()
|
|
||||||
const dailyAddress = modules[0]
|
|
||||||
|
|
||||||
const dailyLimitModule = getCreateDailyLimitExtensionContract(web3).at(dailyAddress)
|
|
||||||
if (await dailyLimitModule.manager.call() !== gnosisSafe.address) {
|
|
||||||
throw new Error('Using an extension of different safe')
|
|
||||||
}
|
|
||||||
|
|
||||||
return dailyLimitModule
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: number): Promise<DailyLimitProps> => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
|
||||||
|
|
||||||
const dailyLimitEth = await dailyLimitModule.dailyLimits(tokenAddress)
|
|
||||||
|
|
||||||
const limit = web3.fromWei(dailyLimitEth[LIMIT_POSITION].valueOf(), 'ether').toString()
|
|
||||||
const spentToday = web3.fromWei(dailyLimitEth[SPENT_TODAY_POS].valueOf(), 'ether').toString()
|
|
||||||
|
|
||||||
return { value: Number(limit), spentToday: Number(spentToday) }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getDailyLimitAddress = async (safeAddress: string) => {
|
|
||||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
|
||||||
|
|
||||||
return dailyLimitModule.address
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getEditDailyLimitData = async (safeAddress: string, token: number, dailyLimit: number) => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
|
||||||
const dailyLimitInWei = web3.toWei(dailyLimit, 'ether')
|
|
||||||
return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimitInWei)
|
|
||||||
}
|
|
|
@ -5,30 +5,10 @@ import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { promisify } from '~/utils/promisify'
|
import { promisify } from '~/utils/promisify'
|
||||||
import GnosisSafeSol from '#/GnosisSafe.json'
|
import GnosisSafeSol from '#/GnosisSafe.json'
|
||||||
import ProxyFactorySol from '#/ProxyFactory.json'
|
import ProxyFactorySol from '#/ProxyFactory.json'
|
||||||
import CreateAndAddModules from '#/CreateAndAddModules.json'
|
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||||
import DailyLimitModule from '#/DailyLimitModule.json'
|
|
||||||
import { calculateGasOf, calculateGasPrice, EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
|
||||||
|
|
||||||
let proxyFactoryMaster
|
let proxyFactoryMaster
|
||||||
let createAndAddModuleMaster
|
|
||||||
let safeMaster
|
let safeMaster
|
||||||
let dailyLimitMaster
|
|
||||||
|
|
||||||
const createModuleDataWrapper = () => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
// eslint-disable-next-line
|
|
||||||
return web3.eth.contract([{"constant":false,"inputs":[{"name":"data","type":"bytes"}],"name":"setup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}])
|
|
||||||
}
|
|
||||||
|
|
||||||
const getModuleDataWrapper = ensureOnce(createModuleDataWrapper)
|
|
||||||
|
|
||||||
function createAndAddModulesData(dataArray) {
|
|
||||||
const ModuleDataWrapper = getModuleDataWrapper()
|
|
||||||
|
|
||||||
const mw = ModuleDataWrapper.at(1)
|
|
||||||
// Remove method id (10) and position of data in payload (64)
|
|
||||||
return dataArray.reduce((acc, data) => acc + mw.setup.getData(data).substr(74), EMPTY_DATA)
|
|
||||||
}
|
|
||||||
|
|
||||||
const createGnosisSafeContract = (web3: any) => {
|
const createGnosisSafeContract = (web3: any) => {
|
||||||
const gnosisSafe = contract(GnosisSafeSol)
|
const gnosisSafe = contract(GnosisSafeSol)
|
||||||
|
@ -44,24 +24,8 @@ const createProxyFactoryContract = (web3: any) => {
|
||||||
return proxyFactory
|
return proxyFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
const createAddExtensionContract = (web3: any) => {
|
|
||||||
const createAndAddModule = contract(CreateAndAddModules)
|
|
||||||
createAndAddModule.setProvider(web3.currentProvider)
|
|
||||||
|
|
||||||
return createAndAddModule
|
|
||||||
}
|
|
||||||
|
|
||||||
const createDailyLimitExtensionContract = (web3: any) => {
|
|
||||||
const dailyLimitModule = contract(DailyLimitModule)
|
|
||||||
dailyLimitModule.setProvider(web3.currentProvider)
|
|
||||||
|
|
||||||
return dailyLimitModule
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getGnosisSafeContract = ensureOnce(createGnosisSafeContract)
|
export const getGnosisSafeContract = ensureOnce(createGnosisSafeContract)
|
||||||
const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract)
|
const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract)
|
||||||
const getCreateAddExtensionContract = ensureOnce(createAddExtensionContract)
|
|
||||||
export const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract)
|
|
||||||
|
|
||||||
const instanciateMasterCopies = async () => {
|
const instanciateMasterCopies = async () => {
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
|
@ -70,17 +34,9 @@ const instanciateMasterCopies = async () => {
|
||||||
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
||||||
proxyFactoryMaster = await ProxyFactory.deployed()
|
proxyFactoryMaster = await ProxyFactory.deployed()
|
||||||
|
|
||||||
// Create AddExtension Master Copy
|
|
||||||
const CreateAndAddExtension = getCreateAddExtensionContract(web3)
|
|
||||||
createAndAddModuleMaster = await CreateAndAddExtension.deployed()
|
|
||||||
|
|
||||||
// Initialize safe master copy
|
// Initialize safe master copy
|
||||||
const GnosisSafe = getGnosisSafeContract(web3)
|
const GnosisSafe = getGnosisSafeContract(web3)
|
||||||
safeMaster = await GnosisSafe.deployed()
|
safeMaster = await GnosisSafe.deployed()
|
||||||
|
|
||||||
// Initialize extension master copy
|
|
||||||
const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3)
|
|
||||||
dailyLimitMaster = await DailyLimitExtension.deployed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY USED IN TEST ENVIRONMENT
|
// ONLY USED IN TEST ENVIRONMENT
|
||||||
|
@ -92,52 +48,12 @@ const createMasterCopies = async () => {
|
||||||
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
||||||
proxyFactoryMaster = await ProxyFactory.new({ from: userAccount, gas: '5000000' })
|
proxyFactoryMaster = await ProxyFactory.new({ from: userAccount, gas: '5000000' })
|
||||||
|
|
||||||
const CreateAndAddExtension = getCreateAddExtensionContract(web3)
|
|
||||||
createAndAddModuleMaster = await CreateAndAddExtension.new({ from: userAccount, gas: '5000000' })
|
|
||||||
|
|
||||||
const GnosisSafe = getGnosisSafeContract(web3)
|
const GnosisSafe = getGnosisSafeContract(web3)
|
||||||
safeMaster = await GnosisSafe.new({ from: userAccount, gas: '6000000' })
|
safeMaster = await GnosisSafe.new({ from: userAccount, gas: '6000000' })
|
||||||
|
|
||||||
const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3)
|
|
||||||
dailyLimitMaster = await DailyLimitExtension.new([], [], { from: userAccount, gas: '5000000' })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initContracts = ensureOnce(process.env.NODE_ENV === 'test' ? createMasterCopies : instanciateMasterCopies)
|
export const initContracts = ensureOnce(process.env.NODE_ENV === 'test' ? createMasterCopies : instanciateMasterCopies)
|
||||||
|
|
||||||
// ANCHOR Method to be used once we enable dailyLimit again
|
|
||||||
// eslint-disable-next-line
|
|
||||||
const getSafeDataWithDailyLimitBasedOn = async (accounts, numConfirmations, dailyLimitInEth) => {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
|
|
||||||
const moduleData = await dailyLimitMaster.contract.setup
|
|
||||||
.getData([0], [web3.toWei(dailyLimitInEth, 'ether')])
|
|
||||||
|
|
||||||
const proxyFactoryData = await proxyFactoryMaster.contract.createProxy
|
|
||||||
.getData(dailyLimitMaster.address, moduleData)
|
|
||||||
|
|
||||||
const modulesCreationData = createAndAddModulesData([proxyFactoryData])
|
|
||||||
|
|
||||||
const createAndAddModuleData = createAndAddModuleMaster.contract.createAndAddModules
|
|
||||||
.getData(proxyFactoryMaster.address, modulesCreationData)
|
|
||||||
|
|
||||||
return safeMaster.contract.setup
|
|
||||||
.getData(accounts, numConfirmations, createAndAddModuleMaster.address, createAndAddModuleData)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const deploySafeContractWithDailyLimit = async (
|
|
||||||
safeAccounts: string[],
|
|
||||||
numConfirmations: number,
|
|
||||||
dailyLimit: number,
|
|
||||||
userAccount: string,
|
|
||||||
) => {
|
|
||||||
const gnosisSafeData = await getSafeDataWithDailyLimitBasedOn(safeAccounts, numConfirmations, dailyLimit)
|
|
||||||
const proxyFactoryData = proxyFactoryMaster.contract.createProxy.getData(safeMaster.address, gnosisSafeData)
|
|
||||||
const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.address)
|
|
||||||
const gasPrice = await calculateGasPrice()
|
|
||||||
|
|
||||||
return proxyFactoryMaster.createProxy(safeMaster.address, gnosisSafeData, { from: userAccount, gas, gasPrice })
|
|
||||||
}
|
|
||||||
|
|
||||||
export const deploySafeContract = async (
|
export const deploySafeContract = async (
|
||||||
safeAccounts: string[],
|
safeAccounts: string[],
|
||||||
numConfirmations: number,
|
numConfirmations: number,
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
import { calculateGasOf, checkReceiptStatus, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
import { calculateGasOf, checkReceiptStatus, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||||
import { type Operation, submitOperation } from '~/logic/safe/safeTxHistory'
|
import { type Operation, submitOperation } from '~/logic/safe/safeTxHistory'
|
||||||
import { getDailyLimitModuleFrom } from '~/logic/contracts/dailyLimitContracts'
|
|
||||||
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
|
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
|
||||||
import { buildSignaturesFrom } from '~/logic/safe/safeTxSigner'
|
import { buildSignaturesFrom } from '~/logic/safe/safeTxSigner'
|
||||||
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSignerEIP712'
|
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSignerEIP712'
|
||||||
|
@ -120,33 +119,3 @@ export const executeTransaction = async (
|
||||||
|
|
||||||
return txHash
|
return txHash
|
||||||
}
|
}
|
||||||
|
|
||||||
export const executeDailyLimit = async (
|
|
||||||
safeAddress: string,
|
|
||||||
to: string,
|
|
||||||
nonce: number,
|
|
||||||
valueInWei: number,
|
|
||||||
sender: string,
|
|
||||||
) => {
|
|
||||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
|
||||||
const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, to, valueInWei)
|
|
||||||
const gas = await calculateGasOf(dailyLimitData, sender, dailyLimitModule.address)
|
|
||||||
const gasPrice = await calculateGasPrice()
|
|
||||||
|
|
||||||
try {
|
|
||||||
const txReceipt = await dailyLimitModule.executeDailyLimit(0, to, valueInWei, { from: sender, gas, gasPrice })
|
|
||||||
await checkReceiptStatus(txReceipt.tx)
|
|
||||||
|
|
||||||
return Promise.resolve(txReceipt.tx)
|
|
||||||
} catch (err) {
|
|
||||||
return Promise.reject(new Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Temporarily disabled for daily limit operations
|
|
||||||
const operation = 0 // CALL for all currencies
|
|
||||||
const data = '' // empty for ETH
|
|
||||||
|
|
||||||
await submitOperation(safeAddress, to, Number(valueInWei), data, operation, nonce, txReceipt.tx, sender, 'execution')
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
import { type Transaction } from '~/routes/safe/store/model/transaction'
|
import { type Transaction } from '~/routes/safe/store/model/transaction'
|
||||||
import { executeDailyLimit, executeTransaction, approveTransaction } from '~/logic/safe/safeBlockchainOperations'
|
import { executeTransaction, approveTransaction } from '~/logic/safe/safeBlockchainOperations'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/WithdrawForm'
|
|
||||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||||
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
||||||
import { storeSubject } from '~/utils/localStorage/transactions'
|
import { storeSubject } from '~/utils/localStorage/transactions'
|
||||||
|
@ -77,16 +76,3 @@ export const processTransaction = async (
|
||||||
|
|
||||||
return txHash
|
return txHash
|
||||||
}
|
}
|
||||||
|
|
||||||
export const withdraw = async (values: Object, safe: Safe, sender: string): Promise<void> => {
|
|
||||||
const safeAddress = safe.get('address')
|
|
||||||
const destination = values[DESTINATION_PARAM]
|
|
||||||
const valueInEth = values[VALUE_PARAM]
|
|
||||||
const valueInWei = getWeb3().toWei(valueInEth, 'ether')
|
|
||||||
const nonce = Date.now()
|
|
||||||
const txHash = await executeDailyLimit(safeAddress, destination, nonce, valueInWei, sender)
|
|
||||||
|
|
||||||
storeSubject(safeAddress, nonce, `Withdraw movement of ${valueInEth}`)
|
|
||||||
|
|
||||||
return txHash
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { List } from 'immutable'
|
import { List } from 'immutable'
|
||||||
import { createAction } from 'redux-actions'
|
import { createAction } from 'redux-actions'
|
||||||
import { makeDailyLimit, type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
|
|
||||||
import { type SafeProps } from '~/routes/safe/store/model/safe'
|
import { type SafeProps } from '~/routes/safe/store/model/safe'
|
||||||
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
|
||||||
|
|
||||||
|
@ -13,9 +12,6 @@ export const buildOwnersFrom = (names: string[], addresses: string[]) => {
|
||||||
return List(owners)
|
return List(owners)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildDailyLimitFrom = (dailyLimit: number, spentToday: number = 0): DailyLimit =>
|
|
||||||
makeDailyLimit({ value: dailyLimit, spentToday })
|
|
||||||
|
|
||||||
const addSafe = createAction(
|
const addSafe = createAction(
|
||||||
ADD_SAFE,
|
ADD_SAFE,
|
||||||
(
|
(
|
||||||
|
@ -24,10 +20,9 @@ const addSafe = createAction(
|
||||||
ownersName: string[], ownersAddress: string[],
|
ownersName: string[], ownersAddress: string[],
|
||||||
): SafeProps => {
|
): SafeProps => {
|
||||||
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
|
||||||
const dailyLimit: DailyLimit = buildDailyLimitFrom(limit)
|
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
address, name, threshold, owners, dailyLimit,
|
address, name, threshold, owners,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,11 +4,9 @@ import { List, Map } from 'immutable'
|
||||||
import { type GlobalState } from '~/store/index'
|
import { type GlobalState } from '~/store/index'
|
||||||
import { makeOwner } from '~/routes/safe/store/model/owner'
|
import { makeOwner } from '~/routes/safe/store/model/owner'
|
||||||
import { type SafeProps, type Safe, makeSafe } from '~/routes/safe/store/model/safe'
|
import { type SafeProps, type Safe, makeSafe } from '~/routes/safe/store/model/safe'
|
||||||
import { makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
|
|
||||||
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
||||||
import { getOwners } from '~/utils/localStorage'
|
import { getOwners } from '~/utils/localStorage'
|
||||||
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
||||||
import { getDailyLimitFrom } from '~/logic/contracts/dailyLimitContracts'
|
|
||||||
|
|
||||||
const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>) => (
|
const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>) => (
|
||||||
safeOwners.map((ownerAddress: string) => {
|
safeOwners.map((ownerAddress: string) => {
|
||||||
|
@ -21,13 +19,11 @@ export const buildSafe = async (storedSafe: Object) => {
|
||||||
const safeAddress = storedSafe.address
|
const safeAddress = storedSafe.address
|
||||||
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
|
const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress)
|
||||||
|
|
||||||
const dailyLimit = makeDailyLimit(await getDailyLimitFrom(safeAddress, 0))
|
|
||||||
const threshold = Number(await gnosisSafe.getThreshold())
|
const threshold = Number(await gnosisSafe.getThreshold())
|
||||||
const owners = List(buildOwnersFrom(await gnosisSafe.getOwners(), getOwners(safeAddress)))
|
const owners = List(buildOwnersFrom(await gnosisSafe.getOwners(), getOwners(safeAddress)))
|
||||||
|
|
||||||
const safe: SafeProps = {
|
const safe: SafeProps = {
|
||||||
address: safeAddress,
|
address: safeAddress,
|
||||||
dailyLimit,
|
|
||||||
name: storedSafe.name,
|
name: storedSafe.name,
|
||||||
threshold,
|
threshold,
|
||||||
owners,
|
owners,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { List, Record } from 'immutable'
|
import { List, Record } from 'immutable'
|
||||||
import type { RecordFactory, RecordOf } from 'immutable'
|
import type { RecordFactory, RecordOf } from 'immutable'
|
||||||
import { type DailyLimit, makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
|
|
||||||
import type { Owner } from '~/routes/safe/store/model/owner'
|
import type { Owner } from '~/routes/safe/store/model/owner'
|
||||||
|
|
||||||
export type SafeProps = {
|
export type SafeProps = {
|
||||||
|
@ -9,7 +8,6 @@ export type SafeProps = {
|
||||||
address: string,
|
address: string,
|
||||||
threshold: number,
|
threshold: number,
|
||||||
owners: List<Owner>,
|
owners: List<Owner>,
|
||||||
dailyLimit: DailyLimit,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeSafe: RecordFactory<SafeProps> = Record({
|
export const makeSafe: RecordFactory<SafeProps> = Record({
|
||||||
|
@ -17,7 +15,6 @@ export const makeSafe: RecordFactory<SafeProps> = Record({
|
||||||
address: '',
|
address: '',
|
||||||
threshold: 0,
|
threshold: 0,
|
||||||
owners: List([]),
|
owners: List([]),
|
||||||
dailyLimit: makeDailyLimit(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export type Safe = RecordOf<SafeProps>
|
export type Safe = RecordOf<SafeProps>
|
||||||
|
|
Loading…
Reference in New Issue