Merge pull request #65 from gnosis/development

Feature - Integration of transaction-history-service V1
This commit is contained in:
Adolfo Panizo 2018-09-06 16:40:45 +02:00 committed by GitHub
commit 3c0e4c0a6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
138 changed files with 80754 additions and 21230 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
node_modules/
build_webpack/

View File

@ -1,13 +1,45 @@
if: (branch = development) OR (branch = master) OR (type = pull_request) OR (tag IS present)
sudo: required
services:
- docker
language: node_js
node_js:
- "8"
- "9"
os:
- linux
env:
- DOCKER_COMPOSE_VERSION=1.22.0
before_install:
# Install custom docker-compose version
- sudo rm /usr/local/bin/docker-compose
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose
- chmod +x docker-compose
- sudo mv docker-compose /usr/local/bin
# Shut down postgres because it blocks our db container's port map to :5432
# it comes enabled by default in docker-compose
- sudo service postgresql stop
# Wait for it to stop
- while sudo lsof -Pi :5432 -sTCP:LISTEN -t; do sleep 1; done
# Needed to deploy pull request and releases
- sudo apt-get -y install python-pip python-dev
- pip install awscli --upgrade --user
before_script:
- yarn global add surge
# Used in the tests of the project
- export NODE_ENV=testing
- git clone https://github.com/gnosis/safe-transaction-history.git
- cd safe-transaction-history
- git checkout develop
- docker-compose build
- docker-compose up -d
# Give some time to docker to enable all services
- sleep 15
- cd ..
after_success:
- cd safe-transaction-history
- docker-compose stop
- cd ..
- |
if [ ${TRAVIS_BRANCH} = "master" ]; then
export NODE_ENV=production;
else
@ -15,6 +47,42 @@ after_success:
fi
- yarn build-storybook
- yarn build
- cd build_webpack/ && cp index.html 200.html && cd ..
- chmod ugo+x ./config/deploy/deploy.sh
- ./config/deploy/deploy.sh
# Pull Request - Deploy it to a review environment
# Travis doesn't do deploy step with pull requests builds
- ./config/travis/deploy_pull_request.sh
# Releases (tagged commits) - Deploy it to a release environment
- ./config/travis/deploy_release.sh
deploy:
# Development environment
- provider: s3
bucket: $DEV_BUCKET_NAME
access_key_id: $AWS_ACCESS_KEY_ID
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: build_webpack
upload-dir: app
on:
branch: development
# Development environment - Storybook
- provider: s3
bucket: $DEV_BUCKET_NAME
access_key_id: $AWS_ACCESS_KEY_ID
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: build_storybook
upload-dir: storybook
on:
branch: development
# Staging environment
- provider: s3
bucket: $STAGING_BUCKET_NAME
access_key_id: $AWS_ACCESS_KEY_ID
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: build_webpack
upload-dir: current
on:
branch: master

View File

@ -1,82 +0,0 @@
#!/bin/bash
echo "Deployment script for gnosis-safe-team"
RANGE=500
number=$RANDOM
let "number %= $RANGE"
# Split on "/", ref: http://stackoverflow.com/a/5257398/689223
REPO_SLUG_ARRAY=(${TRAVIS_REPO_SLUG//\// })
REPO_OWNER=${REPO_SLUG_ARRAY[0]}
REPO_NAME=${REPO_SLUG_ARRAY[1]}
DEPLOY_PATH=./build_webpack
DEPLOY_PATH_STORYBOOK=./build_storybook
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST=()
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then
if [ "$NODE_ENV" == "production" ]
then
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(release-${TRAVIS_PULL_REQUEST}-pr-${number})
else
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(staging-${TRAVIS_PULL_REQUEST}-pr-${number})
fi
elif [ -n "${TRAVIS_TAG// }" ] #TAG is not empty
then
if [ "$NODE_ENV" == "production" ]
then
#sorts the tags and picks the latest
#sort -V does not work on the travis machine
#sort -V ref: http://stackoverflow.com/a/14273595/689223
#sort -t ... ref: http://stackoverflow.com/a/4495368/689223
#reverse with sed ref: http://stackoverflow.com/a/744093/689223
#git tags | ignore release candidates | sort versions | reverse | pick first line
LATEST_TAG=`git tag | grep -v rc | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | sed '1!G;h;$!d' | sed -n 1p`
echo $LATEST_TAG
if [ "$TRAVIS_TAG" == "$LATEST_TAG" ]
then
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(latest)
fi
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(${TRAVIS_TAG}-tag)
fi
else
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(${TRAVIS_BRANCH}-branch)
fi
for DEPLOY_SUBDOMAIN_UNFORMATTED in "${DEPLOY_SUBDOMAIN_UNFORMATTED_LIST[@]}"
do
echo $DEPLOY_SUBDOMAIN_UNFORMATTED
# replaces non alphanumeric symbols with "-"
# sed -r is only supported in linux, ref http://stackoverflow.com/a/2871217/689223
# Domain names follow the RFC1123 spec [a-Z] [0-9] [-]
# The length is limited to 253 characters
# https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
DEPLOY_SUBDOMAIN=`echo "$DEPLOY_SUBDOMAIN_UNFORMATTED" | sed -r 's/[^A-Za-z0-9]+/\-/g'`
echo $DEPLOY_SUBDOMAIN
DEPLOY_DOMAIN=https://${DEPLOY_SUBDOMAIN}-${REPO_NAME}-${REPO_OWNER}.surge.sh
DEPLOY_STORYBOOK=https://storybook-${DEPLOY_SUBDOMAIN}-${REPO_NAME}-${REPO_OWNER}.surge.sh
surge --project ${DEPLOY_PATH} --domain $DEPLOY_DOMAIN;
surge --project ${DEPLOY_PATH_STORYBOOK} --domain $DEPLOY_STORYBOOK
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then
# Using the Issues api instead of the PR api
# Done so because every PR is an issue, and the issues api allows to post general comments,
# while the PR api requires that comments are made to specific files and specific commits
GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments
curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment:\r\n '${DEPLOY_DOMAIN}' \r\n \r\n Storybook book automatic deployment: \r\n '${DEPLOY_STORYBOOK}'"}'
fi
done
echo "Deploy domain: ${DEPLOY_DOMAIN}"

View File

@ -0,0 +1,44 @@
#!/bin/bash
function deploy_pull_request {
REVIEW_ENVIRONMENT_DOMAIN='review.gnosisdev.com'
# Pull request name with "pr" prefix
PULL_REQUEST_NAME="pr$TRAVIS_PULL_REQUEST"
# Feature name without all path. Example gnosis/pm-trading-ui -> pm-trading-ui
REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
# Only alphanumeric characters. Example pm-trading-ui -> pmtradingui
REPO_NAME_ALPHANUMERIC=$(echo $REPO_NAME | sed 's/[^a-zA-Z0-9]//g')
# TRAVIS_PULL_REQUEST contains pull request number
REVIEW_FEATURE_FOLDER="$REPO_NAME_ALPHANUMERIC/$PULL_REQUEST_NAME"
# Specific for this project only
REVIEW_FEATURE_STORYBOOK_FOLDER="${REPO_NAME_ALPHANUMERIC}storybook/$PULL_REQUEST_NAME"
# Deploy safe-team project
aws s3 sync build_webpack s3://${REVIEW_BUCKET_NAME}/${REVIEW_FEATURE_FOLDER} --delete
# Deploy safe-team storybook project
aws s3 sync build_storybook s3://${REVIEW_BUCKET_NAME}/${REVIEW_FEATURE_STORYBOOK_FOLDER} --delete
}
function publish_pull_request_urls_in_github {
REVIEW_FEATURE_URL="https://$PULL_REQUEST_NAME--$REPO_NAME_ALPHANUMERIC.$REVIEW_ENVIRONMENT_DOMAIN"
# Specific for this project only
REVIEW_FEATURE_STORYBOOK_URL="https://$PULL_REQUEST_NAME--${REPO_NAME_ALPHANUMERIC}storybook.$REVIEW_ENVIRONMENT_DOMAIN"
# Using the Issues api instead of the PR api
# Done so because every PR is an issue, and the issues api allows to post general comments,
# while the PR api requires that comments are made to specific files and specific commits
GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments
curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment:\r\n '${REVIEW_FEATURE_URL}' \r\n \r\n Storybook book automatic deployment: \r\n '${REVIEW_FEATURE_STORYBOOK_URL}'"}'
}
# Only:
# - Pull requests
# - Security env variables are available. PR from forks don't have them.
if [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ -n "$AWS_ACCESS_KEY_ID" ]
then
deploy_pull_request
publish_pull_request_urls_in_github
fi

22
config/travis/deploy_release.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
# Only:
# - Tagged commits
# - Security env variables are available.
if [ -n "$TRAVIS_TAG" ] && [ -n "$AWS_ACCESS_KEY_ID" ]
then
REVIEW_ENVIRONMENT_DOMAIN='review.gnosisdev.com'
# Feature name without all path. Example gnosis/pm-trading-ui -> pm-trading-ui
REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
# Only alphanumeric characters. Example pm-trading-ui -> pmtradingui
REPO_NAME_ALPHANUMERIC=$(echo $REPO_NAME | sed 's/[^a-zA-Z0-9]//g')
# Only alphanumeric characters. Example v1.0.0 -> v100
TRAVIS_TAG_ALPHANUMERIC=$(echo $TRAVIS_TAG | sed 's/[^a-zA-Z0-9]//g')
REVIEW_RELEASE_FOLDER="$REPO_NAME_ALPHANUMERIC/$TRAVIS_TAG_ALPHANUMERIC"
# Deploy safe-team release project
aws s3 sync build_webpack s3://${REVIEW_BUCKET_NAME}/${REVIEW_RELEASE_FOLDER} --delete
fi

View File

@ -8,7 +8,7 @@
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "run-with-testrpc -l 40000000 --noVMErrorsOnRPCResponse true 'node scripts/test.js --env=jsdom'",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"precommit": "./precommit.sh",
"flow": "flow",
@ -128,7 +128,7 @@
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"testEnvironment": "node",
"testURL": "https://safe-react",
"testURL": "http://localhost:8000",
"transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/config/jest/cssTransform.js",

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -82,7 +82,7 @@
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 2989,
"sourceUnit": 1689,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
@ -96,10 +96,10 @@
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -109,7 +109,7 @@
}
],
"contractDependencies": [
2988
1688
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
@ -117,7 +117,7 @@
"id": 23,
"linearizedBaseContracts": [
23,
2988
1688
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
@ -264,10 +264,10 @@
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$2988_$",
"typeIdentifier": "t_type$_t_contract$_Proxy_$1688_$",
"typeString": "type(contract Proxy)"
}
},
@ -382,7 +382,7 @@
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 2989,
"sourceUnit": 1689,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
@ -396,10 +396,10 @@
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -409,7 +409,7 @@
}
],
"contractDependencies": [
2988
1688
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
@ -417,7 +417,7 @@
"id": 23,
"linearizedBaseContracts": [
23,
2988
1688
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
@ -564,10 +564,10 @@
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$2988_$",
"typeIdentifier": "t_type$_t_contract$_Proxy_$1688_$",
"typeString": "type(contract Proxy)"
}
},
@ -662,5 +662,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.054Z"
"updatedAt": "2018-08-20T07:44:41.083Z"
}

View File

@ -147,5 +147,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.054Z"
"updatedAt": "2018-08-20T07:44:41.083Z"
}

View File

@ -0,0 +1,171 @@
{
"contractName": "EtherPaymentFallback",
"abi": [
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x6080604052348015600f57600080fd5b50603280601d6000396000f30060806040520000a165627a7a723058208226d93ca47e5b6cb455362823a9ae7ae1ffe3fb79b732dd39f124670f780a070029",
"deployedBytecode": "0x60806040520000a165627a7a723058208226d93ca47e5b6cb455362823a9ae7ae1ffe3fb79b732dd39f124670f780a070029",
"sourceMap": "167:155:2:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;167:155:2;;;;;;;",
"deployedSourceMap": "167:155:2:-;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract EtherPaymentFallback {\n\n /// @dev Fallback function accepts Ether transactions.\n function ()\n external\n payable\n {\n\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
"exportedSymbols": {
"EtherPaymentFallback": [
37
]
},
"id": 38,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 32,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:2"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 37,
"linearizedBaseContracts": [
37
],
"name": "EtherPaymentFallback",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 35,
"nodeType": "Block",
"src": "312:8:2",
"statements": []
},
"documentation": "@dev Fallback function accepts Ether transactions.",
"id": 36,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 33,
"nodeType": "ParameterList",
"parameters": [],
"src": "272:2:2"
},
"payable": true,
"returnParameters": {
"id": 34,
"nodeType": "ParameterList",
"parameters": [],
"src": "312:0:2"
},
"scope": 37,
"src": "263:57:2",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 38,
"src": "167:155:2"
}
],
"src": "0:323:2"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
"exportedSymbols": {
"EtherPaymentFallback": [
37
]
},
"id": 38,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 32,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:2"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 37,
"linearizedBaseContracts": [
37
],
"name": "EtherPaymentFallback",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 35,
"nodeType": "Block",
"src": "312:8:2",
"statements": []
},
"documentation": "@dev Fallback function accepts Ether transactions.",
"id": 36,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 33,
"nodeType": "ParameterList",
"parameters": [],
"src": "272:2:2"
},
"payable": true,
"returnParameters": {
"id": 34,
"nodeType": "ParameterList",
"parameters": [],
"src": "312:0:2"
},
"scope": 37,
"src": "263:57:2",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 38,
"src": "167:155:2"
}
],
"src": "0:323:2"
},
"compiler": {
"name": "solc",
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-08-20T07:44:41.083Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,38 +18,38 @@
],
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
"sourceMap": "203:673:5:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:5;;;;;;;",
"deployedSourceMap": "203:673:5:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:16;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:5;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
"sourceMap": "203:673:7:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:7;;;;;;;",
"deployedSourceMap": "203:673:7:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:16;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:7;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
"source": "pragma solidity 0.4.24;\nimport \"./SelfAuthorized.sol\";\n\n\n/// @title MasterCopy - Base for master copy contracts (should always be first super contract)\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract MasterCopy is SelfAuthorized {\n // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address masterCopy;\n\n /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n /// @param _masterCopy New contract address.\n function changeMasterCopy(address _masterCopy)\n public\n authorized\n {\n // Master copy address cannot be null.\n require(_masterCopy != 0, \"Invalid master copy address provided\");\n masterCopy = _masterCopy;\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
632
813
]
},
"id": 633,
"id": 814,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 607,
"id": 788,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:5"
"src": "0:23:7"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 608,
"id": 789,
"nodeType": "ImportDirective",
"scope": 633,
"sourceUnit": 3066,
"src": "24:30:5",
"scope": 814,
"sourceUnit": 1766,
"src": "24:30:7",
"symbolAliases": [],
"unitAlias": ""
},
@ -59,42 +59,42 @@
"arguments": null,
"baseName": {
"contractScope": null,
"id": 609,
"id": 790,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 3065,
"src": "226:14:5",
"referencedDeclaration": 1765,
"src": "226:14:7",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
},
"id": 610,
"id": 791,
"nodeType": "InheritanceSpecifier",
"src": "226:14:5"
"src": "226:14:7"
}
],
"contractDependencies": [
3065
1765
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 632,
"id": 813,
"linearizedBaseContracts": [
632,
3065
813,
1765
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 612,
"id": 793,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 632,
"src": "465:18:5",
"scope": 813,
"src": "465:18:7",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
@ -102,10 +102,10 @@
"typeString": "address"
},
"typeName": {
"id": 611,
"id": 792,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:5",
"src": "465:7:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -116,9 +116,9 @@
},
{
"body": {
"id": 630,
"id": 811,
"nodeType": "Block",
"src": "711:163:5",
"src": "711:163:7",
"statements": [
{
"expression": {
@ -130,19 +130,19 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 622,
"id": 803,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 620,
"id": 801,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 614,
"src": "776:11:5",
"referencedDeclaration": 795,
"src": "776:11:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -153,14 +153,14 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 621,
"id": 802,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:5",
"src": "791:1:7",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
@ -168,7 +168,7 @@
},
"value": "0"
},
"src": "776:16:5",
"src": "776:16:7",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -177,14 +177,14 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 623,
"id": 804,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:5",
"src": "794:38:7",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
@ -204,21 +204,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 619,
"id": 800,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"src": "768:7:5",
"referencedDeclaration": 3832,
"src": "768:7:7",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 624,
"id": 805,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -226,32 +226,32 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:5",
"src": "768:65:7",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 625,
"id": 806,
"nodeType": "ExpressionStatement",
"src": "768:65:5"
"src": "768:65:7"
},
{
"expression": {
"argumentTypes": null,
"id": 628,
"id": 809,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 626,
"id": 807,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 612,
"src": "843:10:5",
"referencedDeclaration": 793,
"src": "843:10:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -261,68 +261,68 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 627,
"id": 808,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 614,
"src": "856:11:5",
"referencedDeclaration": 795,
"src": "856:11:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:5",
"src": "843:24:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 629,
"id": 810,
"nodeType": "ExpressionStatement",
"src": "843:24:5"
"src": "843:24:7"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 631,
"id": 812,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 617,
"id": 798,
"modifierName": {
"argumentTypes": null,
"id": 616,
"id": 797,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3064,
"src": "696:10:5",
"referencedDeclaration": 1764,
"src": "696:10:7",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:5"
"src": "696:10:7"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 615,
"id": 796,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 614,
"id": 795,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 631,
"src": "652:19:5",
"scope": 812,
"src": "652:19:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -330,10 +330,10 @@
"typeString": "address"
},
"typeName": {
"id": 613,
"id": 794,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:5",
"src": "652:7:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -343,56 +343,56 @@
"visibility": "internal"
}
],
"src": "651:21:5"
"src": "651:21:7"
},
"payable": false,
"returnParameters": {
"id": 618,
"id": 799,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:5"
"src": "711:0:7"
},
"scope": 632,
"src": "626:248:5",
"scope": 813,
"src": "626:248:7",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 633,
"src": "203:673:5"
"scope": 814,
"src": "203:673:7"
}
],
"src": "0:877:5"
"src": "0:877:7"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
632
813
]
},
"id": 633,
"id": 814,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 607,
"id": 788,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:5"
"src": "0:23:7"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 608,
"id": 789,
"nodeType": "ImportDirective",
"scope": 633,
"sourceUnit": 3066,
"src": "24:30:5",
"scope": 814,
"sourceUnit": 1766,
"src": "24:30:7",
"symbolAliases": [],
"unitAlias": ""
},
@ -402,42 +402,42 @@
"arguments": null,
"baseName": {
"contractScope": null,
"id": 609,
"id": 790,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 3065,
"src": "226:14:5",
"referencedDeclaration": 1765,
"src": "226:14:7",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
},
"id": 610,
"id": 791,
"nodeType": "InheritanceSpecifier",
"src": "226:14:5"
"src": "226:14:7"
}
],
"contractDependencies": [
3065
1765
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 632,
"id": 813,
"linearizedBaseContracts": [
632,
3065
813,
1765
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 612,
"id": 793,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 632,
"src": "465:18:5",
"scope": 813,
"src": "465:18:7",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
@ -445,10 +445,10 @@
"typeString": "address"
},
"typeName": {
"id": 611,
"id": 792,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:5",
"src": "465:7:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -459,9 +459,9 @@
},
{
"body": {
"id": 630,
"id": 811,
"nodeType": "Block",
"src": "711:163:5",
"src": "711:163:7",
"statements": [
{
"expression": {
@ -473,19 +473,19 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 622,
"id": 803,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 620,
"id": 801,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 614,
"src": "776:11:5",
"referencedDeclaration": 795,
"src": "776:11:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -496,14 +496,14 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 621,
"id": 802,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:5",
"src": "791:1:7",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
@ -511,7 +511,7 @@
},
"value": "0"
},
"src": "776:16:5",
"src": "776:16:7",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -520,14 +520,14 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 623,
"id": 804,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:5",
"src": "794:38:7",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
@ -547,21 +547,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 619,
"id": 800,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"src": "768:7:5",
"referencedDeclaration": 3832,
"src": "768:7:7",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 624,
"id": 805,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -569,32 +569,32 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:5",
"src": "768:65:7",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 625,
"id": 806,
"nodeType": "ExpressionStatement",
"src": "768:65:5"
"src": "768:65:7"
},
{
"expression": {
"argumentTypes": null,
"id": 628,
"id": 809,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 626,
"id": 807,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 612,
"src": "843:10:5",
"referencedDeclaration": 793,
"src": "843:10:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -604,68 +604,68 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 627,
"id": 808,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 614,
"src": "856:11:5",
"referencedDeclaration": 795,
"src": "856:11:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:5",
"src": "843:24:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 629,
"id": 810,
"nodeType": "ExpressionStatement",
"src": "843:24:5"
"src": "843:24:7"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 631,
"id": 812,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 617,
"id": 798,
"modifierName": {
"argumentTypes": null,
"id": 616,
"id": 797,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3064,
"src": "696:10:5",
"referencedDeclaration": 1764,
"src": "696:10:7",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:5"
"src": "696:10:7"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 615,
"id": 796,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 614,
"id": 795,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 631,
"src": "652:19:5",
"scope": 812,
"src": "652:19:7",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -673,10 +673,10 @@
"typeString": "address"
},
"typeName": {
"id": 613,
"id": 794,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:5",
"src": "652:7:7",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -686,27 +686,27 @@
"visibility": "internal"
}
],
"src": "651:21:5"
"src": "651:21:7"
},
"payable": false,
"returnParameters": {
"id": 618,
"id": 799,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:5"
"src": "711:0:7"
},
"scope": 632,
"src": "626:248:5",
"scope": 813,
"src": "626:248:7",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 633,
"src": "203:673:5"
"scope": 814,
"src": "203:673:7"
}
],
"src": "0:877:5"
"src": "0:877:7"
},
"compiler": {
"name": "solc",
@ -714,5 +714,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.057Z"
"updatedAt": "2018-08-20T07:44:41.087Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -26,14 +26,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
3176
1876
]
},
"id": 3177,
"id": 1877,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3168,
"id": 1868,
"literals": [
"solidity",
"0.4",
@ -48,16 +48,16 @@
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 3176,
"id": 1876,
"linearizedBaseContracts": [
3176
1876
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3174,
"id": 1874,
"nodeType": "Block",
"src": "753:922:19",
"statements": [
@ -65,7 +65,7 @@
"externalReferences": [
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "870:12:19",
@ -74,7 +74,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "993:12:19",
@ -83,7 +83,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1047:12:19",
@ -92,7 +92,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1188:12:19",
@ -101,7 +101,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1115:12:19",
@ -110,7 +110,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1249:12:19",
@ -118,7 +118,7 @@
}
}
],
"id": 3173,
"id": 1873,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:19"
@ -126,7 +126,7 @@
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 3175,
"id": 1875,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -134,15 +134,15 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3171,
"id": 1871,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3170,
"id": 1870,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 3175,
"scope": 1875,
"src": "714:18:19",
"stateVariable": false,
"storageLocation": "default",
@ -151,7 +151,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 3169,
"id": 1869,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "714:5:19",
@ -168,19 +168,19 @@
},
"payable": false,
"returnParameters": {
"id": 3172,
"id": 1872,
"nodeType": "ParameterList",
"parameters": [],
"src": "753:0:19"
},
"scope": 3176,
"scope": 1876,
"src": "695:980:19",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 3177,
"scope": 1877,
"src": "253:1424:19"
}
],
@ -190,14 +190,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
3176
1876
]
},
"id": 3177,
"id": 1877,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3168,
"id": 1868,
"literals": [
"solidity",
"0.4",
@ -212,16 +212,16 @@
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 3176,
"id": 1876,
"linearizedBaseContracts": [
3176
1876
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3174,
"id": 1874,
"nodeType": "Block",
"src": "753:922:19",
"statements": [
@ -229,7 +229,7 @@
"externalReferences": [
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "870:12:19",
@ -238,7 +238,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "993:12:19",
@ -247,7 +247,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1047:12:19",
@ -256,7 +256,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1188:12:19",
@ -265,7 +265,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1115:12:19",
@ -274,7 +274,7 @@
},
{
"transactions": {
"declaration": 3170,
"declaration": 1870,
"isOffset": false,
"isSlot": false,
"src": "1249:12:19",
@ -282,7 +282,7 @@
}
}
],
"id": 3173,
"id": 1873,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:19"
@ -290,7 +290,7 @@
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 3175,
"id": 1875,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -298,15 +298,15 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3171,
"id": 1871,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3170,
"id": 1870,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 3175,
"scope": 1875,
"src": "714:18:19",
"stateVariable": false,
"storageLocation": "default",
@ -315,7 +315,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 3169,
"id": 1869,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "714:5:19",
@ -332,19 +332,19 @@
},
"payable": false,
"returnParameters": {
"id": 3172,
"id": 1872,
"nodeType": "ParameterList",
"parameters": [],
"src": "753:0:19"
},
"scope": 3176,
"scope": 1876,
"src": "695:980:19",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 3177,
"scope": 1877,
"src": "253:1424:19"
}
],
@ -358,28 +358,16 @@
"4": {
"events": {},
"links": {},
"address": "0x7115893bc1477bc22f127bc2d82fcb4dd99e5838",
"transactionHash": "0x1f321cf880f5ec5b189cb1ac1c1c1b71ef8d854fc059c345fea6e6129bb19645"
"address": "0x3a29cf32d22f38b7338874b689a88f185663a1c3",
"transactionHash": "0x86b6895207dff0b3e19c202e140dc9cf823cbfc02672e02636af23a1b580e7e7"
},
"1530013596495": {
"1534750848541": {
"events": {},
"links": {},
"address": "0x18a8eaa498a58752858e5a912c8ff136b0bc6c69",
"transactionHash": "0x7da393438ee13b991e6d94278addb64e86b0c13101efb8a0f0f00d9f86ba51d0"
},
"1530525742205": {
"events": {},
"links": {},
"address": "0x0a25374d1738169d8653e6ee01f464bf4cdc8dea",
"transactionHash": "0x2d7f72a94ced345c372040faa1f51a51f3e8da27a02dd04b9eefef487de3ba05"
},
"1530611935189": {
"events": {},
"links": {},
"address": "0x0b98f9d8fbd164d8d4884a997a3ef8e7275d5e0e",
"transactionHash": "0x2d7f72a94ced345c372040faa1f51a51f3e8da27a02dd04b9eefef487de3ba05"
"address": "0x5b9b42d6e4b2e4bf8d42eba32d46918e10899b66",
"transactionHash": "0xaf733882096b301ccf5bf4a12ebf84616b88927c71cc656cc037fbd892a24104"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-07-03T09:59:18.515Z"
"updatedAt": "2018-08-20T07:50:29.677Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -56,14 +56,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
2988
1688
]
},
"id": 2989,
"id": 1689,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2947,
"id": 1647,
"literals": [
"solidity",
"0.4",
@ -78,19 +78,19 @@
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 2988,
"id": 1688,
"linearizedBaseContracts": [
2988
1688
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 2949,
"id": 1649,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2988,
"scope": 1688,
"src": "363:18:13",
"stateVariable": true,
"storageLocation": "default",
@ -99,7 +99,7 @@
"typeString": "address"
},
"typeName": {
"id": 2948,
"id": 1648,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "363:7:13",
@ -113,7 +113,7 @@
},
{
"body": {
"id": 2965,
"id": 1665,
"nodeType": "Block",
"src": "560:116:13",
"statements": [
@ -127,18 +127,18 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 2957,
"id": 1657,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 2955,
"id": 1655,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2951,
"referencedDeclaration": 1651,
"src": "578:11:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -150,7 +150,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 2956,
"id": 1656,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -174,7 +174,7 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 2958,
"id": 1658,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -201,21 +201,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 2954,
"id": 1654,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"referencedDeclaration": 3832,
"src": "570:7:13",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 2959,
"id": 1659,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -229,25 +229,25 @@
"typeString": "tuple()"
}
},
"id": 2960,
"id": 1660,
"nodeType": "ExpressionStatement",
"src": "570:65:13"
},
{
"expression": {
"argumentTypes": null,
"id": 2963,
"id": 1663,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 2961,
"id": 1661,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2949,
"referencedDeclaration": 1649,
"src": "645:10:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -258,11 +258,11 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 2962,
"id": 1662,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2951,
"referencedDeclaration": 1651,
"src": "658:11:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -275,14 +275,14 @@
"typeString": "address"
}
},
"id": 2964,
"id": 1664,
"nodeType": "ExpressionStatement",
"src": "645:24:13"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 2966,
"id": 1666,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
@ -290,15 +290,15 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2952,
"id": 1652,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2951,
"id": 1651,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2966,
"scope": 1666,
"src": "520:19:13",
"stateVariable": false,
"storageLocation": "default",
@ -307,7 +307,7 @@
"typeString": "address"
},
"typeName": {
"id": 2950,
"id": 1650,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "520:7:13",
@ -324,12 +324,12 @@
},
"payable": false,
"returnParameters": {
"id": 2953,
"id": 1653,
"nodeType": "ParameterList",
"parameters": [],
"src": "560:0:13"
},
"scope": 2988,
"scope": 1688,
"src": "508:168:13",
"stateMutability": "nonpayable",
"superFunction": null,
@ -337,13 +337,13 @@
},
{
"body": {
"id": 2970,
"id": 1670,
"nodeType": "Block",
"src": "826:470:13",
"statements": [
{
"externalReferences": [],
"id": 2969,
"id": 1669,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0)\n {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n}",
"src": "900:396:13"
@ -351,7 +351,7 @@
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 2971,
"id": 1671,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -359,19 +359,19 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2967,
"id": 1667,
"nodeType": "ParameterList",
"parameters": [],
"src": "786:2:13"
},
"payable": true,
"returnParameters": {
"id": 2968,
"id": 1668,
"nodeType": "ParameterList",
"parameters": [],
"src": "826:0:13"
},
"scope": 2988,
"scope": 1688,
"src": "777:519:13",
"stateMutability": "payable",
"superFunction": null,
@ -379,33 +379,33 @@
},
{
"body": {
"id": 2978,
"id": 1678,
"nodeType": "Block",
"src": "1386:34:13",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 2976,
"id": 1676,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2949,
"referencedDeclaration": 1649,
"src": "1403:10:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"functionReturnParameters": 2975,
"id": 2977,
"functionReturnParameters": 1675,
"id": 1677,
"nodeType": "Return",
"src": "1396:17:13"
}
]
},
"documentation": null,
"id": 2979,
"id": 1679,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -413,22 +413,22 @@
"name": "implementation",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2972,
"id": 1672,
"nodeType": "ParameterList",
"parameters": [],
"src": "1325:2:13"
},
"payable": false,
"returnParameters": {
"id": 2975,
"id": 1675,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2974,
"id": 1674,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 2979,
"scope": 1679,
"src": "1373:7:13",
"stateVariable": false,
"storageLocation": "default",
@ -437,7 +437,7 @@
"typeString": "address"
},
"typeName": {
"id": 2973,
"id": 1673,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1373:7:13",
@ -452,7 +452,7 @@
],
"src": "1372:9:13"
},
"scope": 2988,
"scope": 1688,
"src": "1302:118:13",
"stateMutability": "view",
"superFunction": null,
@ -460,7 +460,7 @@
},
{
"body": {
"id": 2986,
"id": 1686,
"nodeType": "Block",
"src": "1505:25:13",
"statements": [
@ -468,7 +468,7 @@
"expression": {
"argumentTypes": null,
"hexValue": "32",
"id": 2984,
"id": 1684,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -483,15 +483,15 @@
},
"value": "2"
},
"functionReturnParameters": 2983,
"id": 2985,
"functionReturnParameters": 1683,
"id": 1685,
"nodeType": "Return",
"src": "1515:8:13"
}
]
},
"documentation": null,
"id": 2987,
"id": 1687,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -499,22 +499,22 @@
"name": "proxyType",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2980,
"id": 1680,
"nodeType": "ParameterList",
"parameters": [],
"src": "1444:2:13"
},
"payable": false,
"returnParameters": {
"id": 2983,
"id": 1683,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2982,
"id": 1682,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 2987,
"scope": 1687,
"src": "1492:7:13",
"stateVariable": false,
"storageLocation": "default",
@ -523,7 +523,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 2981,
"id": 1681,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1492:7:13",
@ -538,14 +538,14 @@
],
"src": "1491:9:13"
},
"scope": 2988,
"scope": 1688,
"src": "1426:104:13",
"stateMutability": "pure",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2989,
"scope": 1689,
"src": "190:1342:13"
}
],
@ -555,14 +555,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
2988
1688
]
},
"id": 2989,
"id": 1689,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2947,
"id": 1647,
"literals": [
"solidity",
"0.4",
@ -577,19 +577,19 @@
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 2988,
"id": 1688,
"linearizedBaseContracts": [
2988
1688
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 2949,
"id": 1649,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2988,
"scope": 1688,
"src": "363:18:13",
"stateVariable": true,
"storageLocation": "default",
@ -598,7 +598,7 @@
"typeString": "address"
},
"typeName": {
"id": 2948,
"id": 1648,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "363:7:13",
@ -612,7 +612,7 @@
},
{
"body": {
"id": 2965,
"id": 1665,
"nodeType": "Block",
"src": "560:116:13",
"statements": [
@ -626,18 +626,18 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 2957,
"id": 1657,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 2955,
"id": 1655,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2951,
"referencedDeclaration": 1651,
"src": "578:11:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -649,7 +649,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 2956,
"id": 1656,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -673,7 +673,7 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 2958,
"id": 1658,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -700,21 +700,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 2954,
"id": 1654,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"referencedDeclaration": 3832,
"src": "570:7:13",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 2959,
"id": 1659,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -728,25 +728,25 @@
"typeString": "tuple()"
}
},
"id": 2960,
"id": 1660,
"nodeType": "ExpressionStatement",
"src": "570:65:13"
},
{
"expression": {
"argumentTypes": null,
"id": 2963,
"id": 1663,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 2961,
"id": 1661,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2949,
"referencedDeclaration": 1649,
"src": "645:10:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -757,11 +757,11 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 2962,
"id": 1662,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2951,
"referencedDeclaration": 1651,
"src": "658:11:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -774,14 +774,14 @@
"typeString": "address"
}
},
"id": 2964,
"id": 1664,
"nodeType": "ExpressionStatement",
"src": "645:24:13"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 2966,
"id": 1666,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
@ -789,15 +789,15 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2952,
"id": 1652,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2951,
"id": 1651,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 2966,
"scope": 1666,
"src": "520:19:13",
"stateVariable": false,
"storageLocation": "default",
@ -806,7 +806,7 @@
"typeString": "address"
},
"typeName": {
"id": 2950,
"id": 1650,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "520:7:13",
@ -823,12 +823,12 @@
},
"payable": false,
"returnParameters": {
"id": 2953,
"id": 1653,
"nodeType": "ParameterList",
"parameters": [],
"src": "560:0:13"
},
"scope": 2988,
"scope": 1688,
"src": "508:168:13",
"stateMutability": "nonpayable",
"superFunction": null,
@ -836,13 +836,13 @@
},
{
"body": {
"id": 2970,
"id": 1670,
"nodeType": "Block",
"src": "826:470:13",
"statements": [
{
"externalReferences": [],
"id": 2969,
"id": 1669,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0)\n {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n}",
"src": "900:396:13"
@ -850,7 +850,7 @@
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 2971,
"id": 1671,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -858,19 +858,19 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2967,
"id": 1667,
"nodeType": "ParameterList",
"parameters": [],
"src": "786:2:13"
},
"payable": true,
"returnParameters": {
"id": 2968,
"id": 1668,
"nodeType": "ParameterList",
"parameters": [],
"src": "826:0:13"
},
"scope": 2988,
"scope": 1688,
"src": "777:519:13",
"stateMutability": "payable",
"superFunction": null,
@ -878,33 +878,33 @@
},
{
"body": {
"id": 2978,
"id": 1678,
"nodeType": "Block",
"src": "1386:34:13",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 2976,
"id": 1676,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2949,
"referencedDeclaration": 1649,
"src": "1403:10:13",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"functionReturnParameters": 2975,
"id": 2977,
"functionReturnParameters": 1675,
"id": 1677,
"nodeType": "Return",
"src": "1396:17:13"
}
]
},
"documentation": null,
"id": 2979,
"id": 1679,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -912,22 +912,22 @@
"name": "implementation",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2972,
"id": 1672,
"nodeType": "ParameterList",
"parameters": [],
"src": "1325:2:13"
},
"payable": false,
"returnParameters": {
"id": 2975,
"id": 1675,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2974,
"id": 1674,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 2979,
"scope": 1679,
"src": "1373:7:13",
"stateVariable": false,
"storageLocation": "default",
@ -936,7 +936,7 @@
"typeString": "address"
},
"typeName": {
"id": 2973,
"id": 1673,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1373:7:13",
@ -951,7 +951,7 @@
],
"src": "1372:9:13"
},
"scope": 2988,
"scope": 1688,
"src": "1302:118:13",
"stateMutability": "view",
"superFunction": null,
@ -959,7 +959,7 @@
},
{
"body": {
"id": 2986,
"id": 1686,
"nodeType": "Block",
"src": "1505:25:13",
"statements": [
@ -967,7 +967,7 @@
"expression": {
"argumentTypes": null,
"hexValue": "32",
"id": 2984,
"id": 1684,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -982,15 +982,15 @@
},
"value": "2"
},
"functionReturnParameters": 2983,
"id": 2985,
"functionReturnParameters": 1683,
"id": 1685,
"nodeType": "Return",
"src": "1515:8:13"
}
]
},
"documentation": null,
"id": 2987,
"id": 1687,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -998,22 +998,22 @@
"name": "proxyType",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2980,
"id": 1680,
"nodeType": "ParameterList",
"parameters": [],
"src": "1444:2:13"
},
"payable": false,
"returnParameters": {
"id": 2983,
"id": 1683,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2982,
"id": 1682,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 2987,
"scope": 1687,
"src": "1492:7:13",
"stateVariable": false,
"storageLocation": "default",
@ -1022,7 +1022,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 2981,
"id": 1681,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1492:7:13",
@ -1037,14 +1037,14 @@
],
"src": "1491:9:13"
},
"scope": 2988,
"scope": 1688,
"src": "1426:104:13",
"stateMutability": "pure",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2989,
"scope": 1689,
"src": "190:1342:13"
}
],
@ -1056,5 +1056,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.083Z"
"updatedAt": "2018-08-20T07:44:41.092Z"
}

View File

@ -47,14 +47,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/ProxyFactory.sol",
"exportedSymbols": {
"ProxyFactory": [
3023
1723
]
},
"id": 3024,
"id": 1724,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2990,
"id": 1690,
"literals": [
"solidity",
"0.4",
@ -66,10 +66,10 @@
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 2991,
"id": 1691,
"nodeType": "ImportDirective",
"scope": 3024,
"sourceUnit": 2989,
"scope": 1724,
"sourceUnit": 1689,
"src": "24:21:14",
"symbolAliases": [],
"unitAlias": ""
@ -77,14 +77,14 @@
{
"baseContracts": [],
"contractDependencies": [
2988
1688
],
"contractKind": "contract",
"documentation": "@title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 3023,
"id": 1723,
"linearizedBaseContracts": [
3023
1723
],
"name": "ProxyFactory",
"nodeType": "ContractDefinition",
@ -92,36 +92,36 @@
{
"anonymous": false,
"documentation": null,
"id": 2995,
"id": 1695,
"name": "ProxyCreation",
"nodeType": "EventDefinition",
"parameters": {
"id": 2994,
"id": 1694,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2993,
"id": 1693,
"indexed": false,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 2995,
"scope": 1695,
"src": "274:11:14",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 2992,
"id": 1692,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "274:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -135,28 +135,28 @@
},
{
"body": {
"id": 3021,
"id": 1721,
"nodeType": "Block",
"src": "634:314:14",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 3009,
"id": 1709,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 3004,
"id": 1704,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3002,
"referencedDeclaration": 1702,
"src": "644:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -167,11 +167,11 @@
"arguments": [
{
"argumentTypes": null,
"id": 3007,
"id": 1707,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2997,
"referencedDeclaration": 1697,
"src": "662:10:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -186,7 +186,7 @@
"typeString": "address"
}
],
"id": 3006,
"id": 1706,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -194,23 +194,23 @@
"nodeType": "NewExpression",
"src": "652:9:14",
"typeDescriptions": {
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$2988_$",
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1688_$",
"typeString": "function (address) returns (contract Proxy)"
},
"typeName": {
"contractScope": null,
"id": 3005,
"id": 1705,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "656:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
}
},
"id": 3008,
"id": 1708,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -220,17 +220,17 @@
"nodeType": "FunctionCall",
"src": "652:21:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
"src": "644:29:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
"id": 3010,
"id": 1710,
"nodeType": "ExpressionStatement",
"src": "644:29:14"
},
@ -241,7 +241,7 @@
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 3014,
"id": 1714,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -250,18 +250,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3011,
"id": 1711,
"name": "data",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2999,
"referencedDeclaration": 1699,
"src": "687:4:14",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 3012,
"id": 1712,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -280,7 +280,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 3013,
"id": 1713,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -302,14 +302,14 @@
}
},
"falseBody": null,
"id": 3016,
"id": 1716,
"nodeType": "IfStatement",
"src": "683:237:14",
"trueBody": {
"externalReferences": [
{
"data": {
"declaration": 2999,
"declaration": 1699,
"isOffset": false,
"isSlot": false,
"src": "860:4:14",
@ -318,7 +318,7 @@
},
{
"proxy": {
"declaration": 3002,
"declaration": 1702,
"isOffset": false,
"isSlot": false,
"src": "827:5:14",
@ -327,7 +327,7 @@
},
{
"data": {
"declaration": 2999,
"declaration": 1699,
"isOffset": false,
"isSlot": false,
"src": "841:4:14",
@ -335,7 +335,7 @@
}
}
],
"id": 3015,
"id": 1715,
"nodeType": "InlineAssembly",
"operations": "{\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0)\n {\n revert(0, 0)\n }\n}",
"src": "784:136:14"
@ -347,14 +347,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 3018,
"id": 1718,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3002,
"referencedDeclaration": 1702,
"src": "935:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
}
@ -362,22 +362,22 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
],
"id": 3017,
"id": 1717,
"name": "ProxyCreation",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2995,
"referencedDeclaration": 1695,
"src": "921:13:14",
"typeDescriptions": {
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$2988_$returns$__$",
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1688_$returns$__$",
"typeString": "function (contract Proxy)"
}
},
"id": 3019,
"id": 1719,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -391,14 +391,14 @@
"typeString": "tuple()"
}
},
"id": 3020,
"id": 1720,
"nodeType": "EmitStatement",
"src": "916:25:14"
}
]
},
"documentation": "@dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @param masterCopy Address of master copy.\n @param data Payload for message call sent to new proxy contract.",
"id": 3022,
"id": 1722,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -406,15 +406,15 @@
"name": "createProxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3000,
"id": 1700,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2997,
"id": 1697,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "553:18:14",
"stateVariable": false,
"storageLocation": "default",
@ -423,7 +423,7 @@
"typeString": "address"
},
"typeName": {
"id": 2996,
"id": 1696,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "553:7:14",
@ -437,10 +437,10 @@
},
{
"constant": false,
"id": 2999,
"id": 1699,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "573:10:14",
"stateVariable": false,
"storageLocation": "default",
@ -449,7 +449,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 2998,
"id": 1698,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "573:5:14",
@ -466,31 +466,31 @@
},
"payable": false,
"returnParameters": {
"id": 3003,
"id": 1703,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3002,
"id": 1702,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "617:11:14",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 3001,
"id": 1701,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "617:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -500,14 +500,14 @@
],
"src": "616:13:14"
},
"scope": 3023,
"scope": 1723,
"src": "532:416:14",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 3024,
"scope": 1724,
"src": "225:725:14"
}
],
@ -517,14 +517,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/ProxyFactory.sol",
"exportedSymbols": {
"ProxyFactory": [
3023
1723
]
},
"id": 3024,
"id": 1724,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2990,
"id": 1690,
"literals": [
"solidity",
"0.4",
@ -536,10 +536,10 @@
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 2991,
"id": 1691,
"nodeType": "ImportDirective",
"scope": 3024,
"sourceUnit": 2989,
"scope": 1724,
"sourceUnit": 1689,
"src": "24:21:14",
"symbolAliases": [],
"unitAlias": ""
@ -547,14 +547,14 @@
{
"baseContracts": [],
"contractDependencies": [
2988
1688
],
"contractKind": "contract",
"documentation": "@title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 3023,
"id": 1723,
"linearizedBaseContracts": [
3023
1723
],
"name": "ProxyFactory",
"nodeType": "ContractDefinition",
@ -562,36 +562,36 @@
{
"anonymous": false,
"documentation": null,
"id": 2995,
"id": 1695,
"name": "ProxyCreation",
"nodeType": "EventDefinition",
"parameters": {
"id": 2994,
"id": 1694,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2993,
"id": 1693,
"indexed": false,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 2995,
"scope": 1695,
"src": "274:11:14",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 2992,
"id": 1692,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "274:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -605,28 +605,28 @@
},
{
"body": {
"id": 3021,
"id": 1721,
"nodeType": "Block",
"src": "634:314:14",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 3009,
"id": 1709,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 3004,
"id": 1704,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3002,
"referencedDeclaration": 1702,
"src": "644:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -637,11 +637,11 @@
"arguments": [
{
"argumentTypes": null,
"id": 3007,
"id": 1707,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2997,
"referencedDeclaration": 1697,
"src": "662:10:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -656,7 +656,7 @@
"typeString": "address"
}
],
"id": 3006,
"id": 1706,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -664,23 +664,23 @@
"nodeType": "NewExpression",
"src": "652:9:14",
"typeDescriptions": {
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$2988_$",
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1688_$",
"typeString": "function (address) returns (contract Proxy)"
},
"typeName": {
"contractScope": null,
"id": 3005,
"id": 1705,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "656:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
}
},
"id": 3008,
"id": 1708,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -690,17 +690,17 @@
"nodeType": "FunctionCall",
"src": "652:21:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
"src": "644:29:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
"id": 3010,
"id": 1710,
"nodeType": "ExpressionStatement",
"src": "644:29:14"
},
@ -711,7 +711,7 @@
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 3014,
"id": 1714,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -720,18 +720,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3011,
"id": 1711,
"name": "data",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2999,
"referencedDeclaration": 1699,
"src": "687:4:14",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 3012,
"id": 1712,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -750,7 +750,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 3013,
"id": 1713,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -772,14 +772,14 @@
}
},
"falseBody": null,
"id": 3016,
"id": 1716,
"nodeType": "IfStatement",
"src": "683:237:14",
"trueBody": {
"externalReferences": [
{
"data": {
"declaration": 2999,
"declaration": 1699,
"isOffset": false,
"isSlot": false,
"src": "860:4:14",
@ -788,7 +788,7 @@
},
{
"proxy": {
"declaration": 3002,
"declaration": 1702,
"isOffset": false,
"isSlot": false,
"src": "827:5:14",
@ -797,7 +797,7 @@
},
{
"data": {
"declaration": 2999,
"declaration": 1699,
"isOffset": false,
"isSlot": false,
"src": "841:4:14",
@ -805,7 +805,7 @@
}
}
],
"id": 3015,
"id": 1715,
"nodeType": "InlineAssembly",
"operations": "{\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0)\n {\n revert(0, 0)\n }\n}",
"src": "784:136:14"
@ -817,14 +817,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 3018,
"id": 1718,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3002,
"referencedDeclaration": 1702,
"src": "935:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
}
@ -832,22 +832,22 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
],
"id": 3017,
"id": 1717,
"name": "ProxyCreation",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2995,
"referencedDeclaration": 1695,
"src": "921:13:14",
"typeDescriptions": {
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$2988_$returns$__$",
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1688_$returns$__$",
"typeString": "function (contract Proxy)"
}
},
"id": 3019,
"id": 1719,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -861,14 +861,14 @@
"typeString": "tuple()"
}
},
"id": 3020,
"id": 1720,
"nodeType": "EmitStatement",
"src": "916:25:14"
}
]
},
"documentation": "@dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @param masterCopy Address of master copy.\n @param data Payload for message call sent to new proxy contract.",
"id": 3022,
"id": 1722,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -876,15 +876,15 @@
"name": "createProxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3000,
"id": 1700,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2997,
"id": 1697,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "553:18:14",
"stateVariable": false,
"storageLocation": "default",
@ -893,7 +893,7 @@
"typeString": "address"
},
"typeName": {
"id": 2996,
"id": 1696,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "553:7:14",
@ -907,10 +907,10 @@
},
{
"constant": false,
"id": 2999,
"id": 1699,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "573:10:14",
"stateVariable": false,
"storageLocation": "default",
@ -919,7 +919,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 2998,
"id": 1698,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "573:5:14",
@ -936,31 +936,31 @@
},
"payable": false,
"returnParameters": {
"id": 3003,
"id": 1703,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3002,
"id": 1702,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 3022,
"scope": 1722,
"src": "617:11:14",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 3001,
"id": 1701,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 2988,
"referencedDeclaration": 1688,
"src": "617:5:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$2988",
"typeIdentifier": "t_contract$_Proxy_$1688",
"typeString": "contract Proxy"
}
},
@ -970,14 +970,14 @@
],
"src": "616:13:14"
},
"scope": 3023,
"scope": 1723,
"src": "532:416:14",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 3024,
"scope": 1724,
"src": "225:725:14"
}
],
@ -991,28 +991,16 @@
"4": {
"events": {},
"links": {},
"address": "0xb91b58a0e2c5f0737cca7226c0ed41ae0f09af7d",
"transactionHash": "0x6c3db596a40030d69889e70063082d7b7979b3d9637e0a1370f10b1f9ea34772"
"address": "0x03991c5ca1c3057aac2a76d3d83d69afbc6947f7",
"transactionHash": "0x8ef777566f16cc1e7271862d04de617bfdd7d30005d78c895a5aa7b48fd2c30d"
},
"1530013596495": {
"1534750848541": {
"events": {},
"links": {},
"address": "0x9c30095bde0e76c19f0184e26dc7179eeab7aa67",
"transactionHash": "0xc52c6b366f718febb548464465461c5974c0f79b7f3f877c111faea2c9fda273"
},
"1530525742205": {
"events": {},
"links": {},
"address": "0x32d2a0e2b94b3282aea36376e601e07c80d89c23",
"transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285"
},
"1530611935189": {
"events": {},
"links": {},
"address": "0x51d27a55e3375e82e5965a1c266596b0239755f3",
"transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285"
"address": "0xb09bcc172050fbd4562da8b229cf3e45dc3045a6",
"transactionHash": "0xe665fef8b7b04e5623d1fc3cdd86dadbbda63ef832c7020e0412343759bbae12"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-07-03T09:59:18.516Z"
"updatedAt": "2018-08-20T07:50:29.679Z"
}

View File

@ -11,14 +11,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
"exportedSymbols": {
"SecuredTokenTransfer": [
3048
1748
]
},
"id": 3049,
"id": 1749,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3025,
"id": 1725,
"literals": [
"solidity",
"0.4",
@ -33,30 +33,30 @@
"contractKind": "contract",
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 3048,
"id": 1748,
"linearizedBaseContracts": [
3048
1748
],
"name": "SecuredTokenTransfer",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3046,
"id": 1746,
"nodeType": "Block",
"src": "590:592:15",
"statements": [
{
"assignments": [
3037
1737
],
"declarations": [
{
"constant": false,
"id": 3037,
"id": 1737,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "600:17:15",
"stateVariable": false,
"storageLocation": "memory",
@ -65,7 +65,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 3036,
"id": 1736,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "600:5:15",
@ -78,14 +78,14 @@
"visibility": "internal"
}
],
"id": 3044,
"id": 1744,
"initialValue": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
"id": 3040,
"id": 1740,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -102,11 +102,11 @@
},
{
"argumentTypes": null,
"id": 3041,
"id": 1741,
"name": "receiver",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3029,
"referencedDeclaration": 1729,
"src": "673:8:15",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -115,11 +115,11 @@
},
{
"argumentTypes": null,
"id": 3042,
"id": 1742,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3031,
"referencedDeclaration": 1731,
"src": "683:6:15",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
@ -144,18 +144,18 @@
],
"expression": {
"argumentTypes": null,
"id": 3038,
"id": 1738,
"name": "abi",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4023,
"referencedDeclaration": 3815,
"src": "620:3:15",
"typeDescriptions": {
"typeIdentifier": "t_magic_abi",
"typeString": "abi"
}
},
"id": 3039,
"id": 1739,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -169,7 +169,7 @@
"typeString": "function (string memory) pure returns (bytes memory)"
}
},
"id": 3043,
"id": 1743,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -190,7 +190,7 @@
"externalReferences": [
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1061:11:15",
@ -199,7 +199,7 @@
},
{
"data": {
"declaration": 3037,
"declaration": 1737,
"isOffset": false,
"isSlot": false,
"src": "857:4:15",
@ -208,7 +208,7 @@
},
{
"token": {
"declaration": 3027,
"declaration": 1727,
"isOffset": false,
"isSlot": false,
"src": "824:5:15",
@ -217,7 +217,7 @@
},
{
"data": {
"declaration": 3037,
"declaration": 1737,
"isOffset": false,
"isSlot": false,
"src": "838:4:15",
@ -226,7 +226,7 @@
},
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1012:11:15",
@ -235,7 +235,7 @@
},
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1148:11:15",
@ -243,7 +243,7 @@
}
}
],
"id": 3045,
"id": 1745,
"nodeType": "InlineAssembly",
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
"src": "764:418:15"
@ -251,7 +251,7 @@
]
},
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
"id": 3047,
"id": 1747,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -259,15 +259,15 @@
"name": "transferToken",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3032,
"id": 1732,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3027,
"id": 1727,
"name": "token",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "463:13:15",
"stateVariable": false,
"storageLocation": "default",
@ -276,7 +276,7 @@
"typeString": "address"
},
"typeName": {
"id": 3026,
"id": 1726,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "463:7:15",
@ -290,10 +290,10 @@
},
{
"constant": false,
"id": 3029,
"id": 1729,
"name": "receiver",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "487:16:15",
"stateVariable": false,
"storageLocation": "default",
@ -302,7 +302,7 @@
"typeString": "address"
},
"typeName": {
"id": 3028,
"id": 1728,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "487:7:15",
@ -316,10 +316,10 @@
},
{
"constant": false,
"id": 3031,
"id": 1731,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "513:14:15",
"stateVariable": false,
"storageLocation": "default",
@ -328,7 +328,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 3030,
"id": 1730,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "513:7:15",
@ -345,15 +345,15 @@
},
"payable": false,
"returnParameters": {
"id": 3035,
"id": 1735,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3034,
"id": 1734,
"name": "transferred",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "568:16:15",
"stateVariable": false,
"storageLocation": "default",
@ -362,7 +362,7 @@
"typeString": "bool"
},
"typeName": {
"id": 3033,
"id": 1733,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "568:4:15",
@ -377,14 +377,14 @@
],
"src": "567:18:15"
},
"scope": 3048,
"scope": 1748,
"src": "430:752:15",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "internal"
}
],
"scope": 3049,
"scope": 1749,
"src": "133:1051:15"
}
],
@ -394,14 +394,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
"exportedSymbols": {
"SecuredTokenTransfer": [
3048
1748
]
},
"id": 3049,
"id": 1749,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3025,
"id": 1725,
"literals": [
"solidity",
"0.4",
@ -416,30 +416,30 @@
"contractKind": "contract",
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 3048,
"id": 1748,
"linearizedBaseContracts": [
3048
1748
],
"name": "SecuredTokenTransfer",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3046,
"id": 1746,
"nodeType": "Block",
"src": "590:592:15",
"statements": [
{
"assignments": [
3037
1737
],
"declarations": [
{
"constant": false,
"id": 3037,
"id": 1737,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "600:17:15",
"stateVariable": false,
"storageLocation": "memory",
@ -448,7 +448,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 3036,
"id": 1736,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "600:5:15",
@ -461,14 +461,14 @@
"visibility": "internal"
}
],
"id": 3044,
"id": 1744,
"initialValue": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
"id": 3040,
"id": 1740,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -485,11 +485,11 @@
},
{
"argumentTypes": null,
"id": 3041,
"id": 1741,
"name": "receiver",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3029,
"referencedDeclaration": 1729,
"src": "673:8:15",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -498,11 +498,11 @@
},
{
"argumentTypes": null,
"id": 3042,
"id": 1742,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3031,
"referencedDeclaration": 1731,
"src": "683:6:15",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
@ -527,18 +527,18 @@
],
"expression": {
"argumentTypes": null,
"id": 3038,
"id": 1738,
"name": "abi",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4023,
"referencedDeclaration": 3815,
"src": "620:3:15",
"typeDescriptions": {
"typeIdentifier": "t_magic_abi",
"typeString": "abi"
}
},
"id": 3039,
"id": 1739,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -552,7 +552,7 @@
"typeString": "function (string memory) pure returns (bytes memory)"
}
},
"id": 3043,
"id": 1743,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -573,7 +573,7 @@
"externalReferences": [
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1061:11:15",
@ -582,7 +582,7 @@
},
{
"data": {
"declaration": 3037,
"declaration": 1737,
"isOffset": false,
"isSlot": false,
"src": "857:4:15",
@ -591,7 +591,7 @@
},
{
"token": {
"declaration": 3027,
"declaration": 1727,
"isOffset": false,
"isSlot": false,
"src": "824:5:15",
@ -600,7 +600,7 @@
},
{
"data": {
"declaration": 3037,
"declaration": 1737,
"isOffset": false,
"isSlot": false,
"src": "838:4:15",
@ -609,7 +609,7 @@
},
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1012:11:15",
@ -618,7 +618,7 @@
},
{
"transferred": {
"declaration": 3034,
"declaration": 1734,
"isOffset": false,
"isSlot": false,
"src": "1148:11:15",
@ -626,7 +626,7 @@
}
}
],
"id": 3045,
"id": 1745,
"nodeType": "InlineAssembly",
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
"src": "764:418:15"
@ -634,7 +634,7 @@
]
},
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
"id": 3047,
"id": 1747,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -642,15 +642,15 @@
"name": "transferToken",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 3032,
"id": 1732,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3027,
"id": 1727,
"name": "token",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "463:13:15",
"stateVariable": false,
"storageLocation": "default",
@ -659,7 +659,7 @@
"typeString": "address"
},
"typeName": {
"id": 3026,
"id": 1726,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "463:7:15",
@ -673,10 +673,10 @@
},
{
"constant": false,
"id": 3029,
"id": 1729,
"name": "receiver",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "487:16:15",
"stateVariable": false,
"storageLocation": "default",
@ -685,7 +685,7 @@
"typeString": "address"
},
"typeName": {
"id": 3028,
"id": 1728,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "487:7:15",
@ -699,10 +699,10 @@
},
{
"constant": false,
"id": 3031,
"id": 1731,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "513:14:15",
"stateVariable": false,
"storageLocation": "default",
@ -711,7 +711,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 3030,
"id": 1730,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "513:7:15",
@ -728,15 +728,15 @@
},
"payable": false,
"returnParameters": {
"id": 3035,
"id": 1735,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3034,
"id": 1734,
"name": "transferred",
"nodeType": "VariableDeclaration",
"scope": 3047,
"scope": 1747,
"src": "568:16:15",
"stateVariable": false,
"storageLocation": "default",
@ -745,7 +745,7 @@
"typeString": "bool"
},
"typeName": {
"id": 3033,
"id": 1733,
"name": "bool",
"nodeType": "ElementaryTypeName",
"src": "568:4:15",
@ -760,14 +760,14 @@
],
"src": "567:18:15"
},
"scope": 3048,
"scope": 1748,
"src": "430:752:15",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "internal"
}
],
"scope": 3049,
"scope": 1749,
"src": "133:1051:15"
}
],
@ -779,5 +779,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.084Z"
"updatedAt": "2018-08-20T07:44:41.093Z"
}

View File

@ -11,14 +11,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
3065
1765
]
},
"id": 3066,
"id": 1766,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3050,
"id": 1750,
"literals": [
"solidity",
"0.4",
@ -33,16 +33,16 @@
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 3065,
"id": 1765,
"linearizedBaseContracts": [
3065
1765
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3063,
"id": 1763,
"nodeType": "Block",
"src": "204:112:16",
"statements": [
@ -56,7 +56,7 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 3058,
"id": 1758,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -65,18 +65,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3053,
"id": 1753,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4036,
"referencedDeclaration": 3828,
"src": "222:3:16",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 3054,
"id": 1754,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -97,14 +97,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 3056,
"id": 1756,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4055,
"referencedDeclaration": 3851,
"src": "244:4:16",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
}
@ -112,11 +112,11 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
],
"id": 3055,
"id": 1755,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -129,7 +129,7 @@
},
"typeName": "address"
},
"id": 3057,
"id": 1757,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -152,7 +152,7 @@
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 3059,
"id": 1759,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -179,21 +179,21 @@
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 3052,
"id": 1752,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"referencedDeclaration": 3832,
"src": "214:7:16",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 3060,
"id": 1760,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -207,23 +207,23 @@
"typeString": "tuple()"
}
},
"id": 3061,
"id": 1761,
"nodeType": "ExpressionStatement",
"src": "214:84:16"
},
{
"id": 3062,
"id": 1762,
"nodeType": "PlaceholderStatement",
"src": "308:1:16"
}
]
},
"documentation": null,
"id": 3064,
"id": 1764,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 3051,
"id": 1751,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:16"
@ -232,7 +232,7 @@
"visibility": "internal"
}
],
"scope": 3066,
"scope": 1766,
"src": "152:166:16"
}
],
@ -242,14 +242,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
3065
1765
]
},
"id": 3066,
"id": 1766,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 3050,
"id": 1750,
"literals": [
"solidity",
"0.4",
@ -264,16 +264,16 @@
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 3065,
"id": 1765,
"linearizedBaseContracts": [
3065
1765
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 3063,
"id": 1763,
"nodeType": "Block",
"src": "204:112:16",
"statements": [
@ -287,7 +287,7 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 3058,
"id": 1758,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -296,18 +296,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 3053,
"id": 1753,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4036,
"referencedDeclaration": 3828,
"src": "222:3:16",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 3054,
"id": 1754,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -328,14 +328,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 3056,
"id": 1756,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4055,
"referencedDeclaration": 3851,
"src": "244:4:16",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
}
@ -343,11 +343,11 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
"typeString": "contract SelfAuthorized"
}
],
"id": 3055,
"id": 1755,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -360,7 +360,7 @@
},
"typeName": "address"
},
"id": 3057,
"id": 1757,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -383,7 +383,7 @@
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 3059,
"id": 1759,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -410,21 +410,21 @@
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 3052,
"id": 1752,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
4039,
4040
3831,
3832
],
"referencedDeclaration": 4040,
"referencedDeclaration": 3832,
"src": "214:7:16",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 3060,
"id": 1760,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -438,23 +438,23 @@
"typeString": "tuple()"
}
},
"id": 3061,
"id": 1761,
"nodeType": "ExpressionStatement",
"src": "214:84:16"
},
{
"id": 3062,
"id": 1762,
"nodeType": "PlaceholderStatement",
"src": "308:1:16"
}
]
},
"documentation": null,
"id": 3064,
"id": 1764,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 3051,
"id": 1751,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:16"
@ -463,7 +463,7 @@
"visibility": "internal"
}
],
"scope": 3066,
"scope": 1766,
"src": "152:166:16"
}
],
@ -475,5 +475,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-29T09:01:22.084Z"
"updatedAt": "2018-08-20T07:44:41.093Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
// @flow
import { fetchProvider } from '~/wallets/store/actions'
import { fetchProvider } from '~/logic/wallets/store/actions'
export default {
fetchProvider,

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { providerNameSelector } from '~/wallets/store/selectors/index'
import { providerNameSelector } from '~/logic/wallets/store/selectors'
export default createStructuredSelector({
provider: providerNameSelector,

View File

@ -1,6 +1,6 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { type FieldValidator } from 'final-form'
import { getWeb3 } from '~/logic/wallets/getWeb3'
type Field = boolean | string | null | typeof undefined

10
src/config/development.js Normal file
View File

@ -0,0 +1,10 @@
// @flow
import { TX_SERVICE_HOST, ENABLED_TX_SERVICE_MODULES, ENABLED_TX_SERVICE_REMOVAL_SENDER } from '~/config/names'
const devConfig = {
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
[ENABLED_TX_SERVICE_MODULES]: false,
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
}
export default devConfig

40
src/config/index.js Normal file
View File

@ -0,0 +1,40 @@
// @flow
import { ensureOnce } from '~/utils/singleton'
import { TX_SERVICE_HOST, ENABLED_TX_SERVICE_MODULES, ENABLED_TX_SERVICE_REMOVAL_SENDER } from '~/config/names'
import devConfig from './development'
import testConfig from './testing'
import prodConfig from './production'
const configuration = () => {
if (process.env.NODE_ENV === 'test') {
return testConfig
}
if (process.env.NODE_ENV === 'production') {
return prodConfig
}
return devConfig
}
const getConfig = ensureOnce(configuration)
export const getTxServiceHost = () => {
const config = getConfig()
return config[TX_SERVICE_HOST]
}
export const getTxServiceUriFrom = (safeAddress: string) => `safes/${safeAddress}/transactions/`
export const allowedModulesInTxHistoryService = () => {
const config = getConfig()
return config[ENABLED_TX_SERVICE_MODULES]
}
export const allowedRemoveSenderInTxHistoryService = () => {
const config = getConfig()
return config[ENABLED_TX_SERVICE_REMOVAL_SENDER]
}

5
src/config/names.js Normal file
View File

@ -0,0 +1,5 @@
// @flow
export const TX_SERVICE_HOST = 'tsh'
export const ENABLED_TX_SERVICE_MODULES = 'tsm'
export const ENABLED_TX_SERVICE_REMOVAL_SENDER = 'trs'

10
src/config/production.js Normal file
View File

@ -0,0 +1,10 @@
// @flow
import { TX_SERVICE_HOST, ENABLED_TX_SERVICE_MODULES, ENABLED_TX_SERVICE_REMOVAL_SENDER } from '~/config/names'
const prodConfig = {
[TX_SERVICE_HOST]: 'https://safe-transaction-history.dev.gnosisdev.com/api/v1/',
[ENABLED_TX_SERVICE_MODULES]: false,
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
}
export default prodConfig

10
src/config/testing.js Normal file
View File

@ -0,0 +1,10 @@
// @flow
import { TX_SERVICE_HOST, ENABLED_TX_SERVICE_MODULES, ENABLED_TX_SERVICE_REMOVAL_SENDER } from '~/config/names'
const testConfig = {
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
[ENABLED_TX_SERVICE_MODULES]: false,
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
}
export default testConfig

View File

@ -0,0 +1,48 @@
// @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)
}

View File

@ -1,13 +1,13 @@
// @flow
import contract from 'truffle-contract'
import { ensureOnce } from '~/utils/singleton'
import { getWeb3 } from '~/wallets/getWeb3'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
import GnosisSafeSol from '#/GnosisSafeTeamEdition.json'
import ProxyFactorySol from '#/ProxyFactory.json'
import CreateAndAddModules from '#/CreateAndAddModules.json'
import DailyLimitModule from '#/DailyLimitModule.json'
import { calculateGasOf, calculateGasPrice, EMPTY_DATA } from '~/wallets/ethTransactions'
import { calculateGasOf, calculateGasPrice, EMPTY_DATA } from '~/logic/wallets/ethTransactions'
let proxyFactoryMaster
let createAndAddModuleMaster

View File

@ -0,0 +1,87 @@
// @flow
import { calculateGasOf, checkReceiptStatus, calculateGasPrice } from '~/logic/wallets/ethTransactions'
import { type Operation, submitOperation } from '~/logic/safe/safeTxHistory'
import { getDailyLimitModuleFrom } from '~/logic/contracts/dailyLimitContracts'
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
export const approveTransaction = async (
safeAddress: string,
to: string,
valueInWei: number,
data: string,
operation: Operation,
nonce: number,
sender: string,
) => {
const gasPrice = await calculateGasPrice()
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const txData = gnosisSafe.contract.approveTransactionWithParameters.getData(to, valueInWei, data, operation, nonce)
const gas = await calculateGasOf(txData, sender, safeAddress)
const txReceipt = await gnosisSafe
.approveTransactionWithParameters(to, valueInWei, data, operation, nonce, { from: sender, gas, gasPrice })
const txHash = txReceipt.tx
await checkReceiptStatus(txHash)
await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'confirmation')
return txHash
}
export const executeTransaction = async (
safeAddress: string,
to: string,
valueInWei: number,
data: string,
operation: Operation,
nonce: number,
sender: string,
) => {
const gasPrice = await calculateGasPrice()
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const txConfirmationData =
gnosisSafe.contract.execTransactionIfApproved.getData(to, valueInWei, data, operation, nonce)
const numOwners = await gnosisSafe.getOwners()
const gas = await calculateGasOf(txConfirmationData, sender, safeAddress)
const gasIncludingRemovingStoreUpfront = gas + (numOwners.length * 15000)
const txReceipt = await gnosisSafe.execTransactionIfApproved(
to,
valueInWei,
data,
operation,
nonce,
{ from: sender, gas: gasIncludingRemovingStoreUpfront, gasPrice },
)
const txHash = txReceipt.tx
await checkReceiptStatus(txHash)
await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'execution')
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()
const txReceipt = await dailyLimitModule.executeDailyLimit(0, to, valueInWei, { from: sender, gas, gasPrice })
checkReceiptStatus(txReceipt.tx)
/*
// 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')
*/
return txReceipt.tx
}

View File

@ -0,0 +1,90 @@
// @flow
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { executeDailyLimit, executeTransaction, approveTransaction } from '~/logic/safe/safeBlockchainOperations'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
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 { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
import { storeSubject } from '~/utils/localStorage/transactions'
export const TX_NAME_PARAM = 'txName'
export const TX_DESTINATION_PARAM = 'txDestination'
export const TX_VALUE_PARAM = 'txValue'
export const EXECUTED_CONFIRMATION_HASH = 'EXECUTED'
const hasOneOwner = (safe: Safe) => {
const owners = safe.get('owners')
if (!owners) {
throw new Error('Received a Safe without owners when creating a tx')
}
return owners.count() === 1
}
export const getSafeEthereumInstance = async (safeAddress: string) => {
const web3 = getWeb3()
const GnosisSafe = await getGnosisSafeContract(web3)
return GnosisSafe.at(safeAddress)
}
export const createTransaction = async (
safe: Safe,
name: string,
to: string,
value: number,
nonce: number,
sender: string,
data: string = EMPTY_DATA,
) => {
const web3 = getWeb3()
const safeAddress = safe.get('address')
const threshold = safe.get('threshold')
const valueInWei = web3.toWei(value, 'ether')
const CALL = 0
const isExecution = hasOneOwner(safe) || threshold === 1
const txHash = isExecution
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
storeSubject(safeAddress, nonce, name)
return txHash
}
export const processTransaction = async (
safeAddress: string,
tx: Transaction,
alreadyConfirmed: number,
sender: string,
threshold: number,
) => {
const nonce = tx.get('nonce')
const valueInWei = tx.get('value')
const to = tx.get('destination')
const data = tx.get('data')
const CALL = 0
const thresholdReached = threshold === alreadyConfirmed + 1
const txHash = thresholdReached
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
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
}

View File

@ -0,0 +1,72 @@
// @flow
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { getTxServiceUriFrom, getTxServiceHost } from '~/config'
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
export type TxServiceType = 'confirmation' | 'execution' | 'initialised'
export type Operation = 0 | 1 | 2
const calculateBodyFrom = async (
safeAddress: string,
to: string,
valueInWei: number,
data: string,
operation: Operation,
nonce: number,
transactionHash: string,
sender: string,
type: TxServiceType,
) => {
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const contractTransactionHash = await gnosisSafe.getTransactionHash(to, valueInWei, data, operation, nonce)
return JSON.stringify({
to: getWeb3().toChecksumAddress(to),
value: valueInWei,
data,
operation,
nonce,
contractTransactionHash,
transactionHash,
sender: getWeb3().toChecksumAddress(sender),
type,
})
}
export const buildTxServiceUrlFrom = (safeAddress: string) => {
const host = getTxServiceHost()
const address = getWeb3().toChecksumAddress(safeAddress)
const base = getTxServiceUriFrom(address)
return `${host}${base}`
}
export const submitOperation = async (
safeAddress: string,
to: string,
valueInWei: number,
data: string,
operation: Operation,
nonce: number,
txHash: string,
sender: string,
type: TxServiceType,
) => {
const url = buildTxServiceUrlFrom(safeAddress)
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json',
}
const body = await calculateBodyFrom(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, type)
const response = await fetch(url, {
method: 'POST',
headers,
body,
})
if (response.status !== 202) {
return Promise.reject(new Error('Error submitting the transaction'))
}
return Promise.resolve()
}

View File

@ -1,6 +1,6 @@
// @flow
import { BigNumber } from 'bignumber.js'
import { getWeb3 } from '~/wallets/getWeb3'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
import { enhancedFetch } from '~/utils/fetch'

View File

@ -1,7 +1,7 @@
// @flow
import { BigNumber } from 'bignumber.js'
import Web3 from 'web3'
import type { ProviderProps } from '~/wallets/store/model/provider'
import type { ProviderProps } from '~/logic/wallets/store/model/provider'
import { promisify } from '~/utils/promisify'
let web3

View File

@ -1,6 +1,6 @@
// @flow
import { createAction } from 'redux-actions'
import { type Provider } from '~/wallets/store/model/provider'
import { type Provider } from '~/logic/wallets/store/model/provider'
export const ADD_PROVIDER = 'ADD_PROVIDER'

View File

@ -1,8 +1,8 @@
// @flow
import type { Dispatch as ReduxDispatch } from 'redux'
import { getProviderInfo } from '~/wallets/getWeb3'
import type { ProviderProps } from '~/wallets/store/model/provider'
import { makeProvider } from '~/wallets/store/model/provider'
import { getProviderInfo } from '~/logic/wallets/getWeb3'
import type { ProviderProps } from '~/logic/wallets/store/model/provider'
import { makeProvider } from '~/logic/wallets/store/model/provider'
import addProvider from './addProvider'
export const processProviderResponse = (dispatch: ReduxDispatch<*>, response: ProviderProps) => {

View File

@ -1,7 +1,7 @@
// @flow
import { handleActions, type ActionType } from 'redux-actions'
import { makeProvider, type Provider } from '~/wallets/store/model/provider'
import addProvider, { ADD_PROVIDER } from '~/wallets/store/actions/addProvider'
import { makeProvider, type Provider } from '~/logic/wallets/store/model/provider'
import addProvider, { ADD_PROVIDER } from '~/logic/wallets/store/actions/addProvider'
export const PROVIDER_REDUCER_ID = 'providers'

View File

@ -1,7 +1,7 @@
// @flow
import { createSelector } from 'reselect'
import type { Provider } from '~/wallets/store/model/provider'
import { PROVIDER_REDUCER_ID } from '~/wallets/store/reducer/provider'
import type { Provider } from '~/logic/wallets/store/model/provider'
import { PROVIDER_REDUCER_ID } from '~/logic/wallets/store/reducer/provider'
const providerSelector = (state: any): Provider => state[PROVIDER_REDUCER_ID]

View File

@ -1,5 +1,5 @@
// @flow
import { PROVIDER_REDUCER_ID } from '~/wallets/store/reducer/provider'
import { PROVIDER_REDUCER_ID } from '~/logic/wallets/store/reducer/provider'
import { userAccountSelector } from '../selectors'
import { ProviderFactory } from './builder/index.builder'

View File

@ -1,6 +1,6 @@
// @flow
import type { Provider } from '~/wallets/store/model/provider'
import { makeProvider } from '~/wallets/store/model/provider'
import type { Provider } from '~/logic/wallets/store/model/provider'
import { makeProvider } from '~/logic/wallets/store/model/provider'
class ProviderBuilder {
provider: Provider

View File

@ -1,5 +1,5 @@
// @flow
import { PROVIDER_REDUCER_ID } from '~/wallets/store/reducer/provider'
import { PROVIDER_REDUCER_ID } from '~/logic/wallets/store/reducer/provider'
import { providerNameSelector } from '../selectors'
import { ProviderFactory } from './builder/index.builder'

View File

@ -1,9 +1,9 @@
// @flow
import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import providerReducer, { PROVIDER_REDUCER_ID } from '~/wallets/store/reducer/provider'
import type { ProviderProps } from '~/wallets/store/model/provider'
import { makeProvider } from '~/wallets/store/model/provider'
import providerReducer, { PROVIDER_REDUCER_ID } from '~/logic/wallets/store/reducer/provider'
import type { ProviderProps } from '~/logic/wallets/store/model/provider'
import { makeProvider } from '~/logic/wallets/store/model/provider'
import { processProviderResponse } from '../actions/fetchProvider'
const providerReducerTests = () => {

View File

@ -1,5 +1,5 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { BigNumber } from 'bignumber.js'
export const toNative = async (amt: string | number | BigNumber, decimal: number): Promise<BigNumber> => {

View File

@ -4,7 +4,7 @@ import { State, Store } from '@sambego/storybook-state'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import { getAccountsFrom, getThresholdFrom } from '~/routes/open/utils/safeDataExtractor'
import { getProviderInfo } from '~/wallets/getWeb3'
import { getProviderInfo } from '~/logic/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import Component from './Layout'

View File

@ -4,7 +4,7 @@ import * as React from 'react'
import * as TestUtils from 'react-dom/test-utils'
import Layout from '~/routes/open/components/Layout'
import { FIELD_CONFIRMATIONS, FIELD_OWNERS } from '~/routes/open/components/fields'
import { getProviderInfo } from '~/wallets/getWeb3'
import { getProviderInfo } from '~/logic/wallets/getWeb3'
import Wrapper from '~/test/utils/Wrapper'
import { CONFIRMATIONS_ERROR } from '~/routes/open/components/SafeForm'

View File

@ -5,7 +5,7 @@ import * as TestUtils from 'react-dom/test-utils'
import GnoForm from '~/components/forms/GnoForm'
import { FIELD_OWNERS } from '~/routes/open/components/fields'
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
import { getProviderInfo } from '~/wallets/getWeb3'
import { getProviderInfo } from '~/logic/wallets/getWeb3'
import Wrapper from '~/test/utils/Wrapper'
import { ADDRESS_REPEATED_ERROR } from '~/components/forms/validator'
import Owners from './index'

View File

@ -4,9 +4,9 @@ import { connect } from 'react-redux'
import Page from '~/components/layout/Page'
import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom, getDailyLimitFrom } from '~/routes/open/utils/safeDataExtractor'
import { getWeb3 } from '~/wallets/getWeb3'
import { getGnosisSafeContract, deploySafeContract, initContracts } from '~/wallets/safeContracts'
import { checkReceiptStatus } from '~/wallets/ethTransactions'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { getGnosisSafeContract, deploySafeContract, initContracts } from '~/logic/contracts/safeContracts'
import { checkReceiptStatus } from '~/logic/wallets/ethTransactions'
import selector from './selector'
import actions, { type Actions, type AddSafe } from './actions'
import Layout from '../components/Layout'

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { providerNameSelector, userAccountSelector } from '~/wallets/store/selectors/index'
import { providerNameSelector, userAccountSelector } from '~/logic/wallets/store/selectors'
export default createStructuredSelector({
provider: providerNameSelector,

View File

@ -5,8 +5,8 @@ import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { type Safe } from '~/routes/safe/store/model/safe'
import { type Owner, makeOwner } from '~/routes/safe/store/model/owner'
import { getSafeEthereumInstance, createTransaction } from '~/wallets/createTransactions'
import { setOwners } from '~/utils/localStorage'
import { getSafeEthereumInstance, createTransaction } from '~/logic/safe/safeFrontendOperations'
import AddOwnerForm, { NAME_PARAM, OWNER_ADDRESS_PARAM, INCREASE_PARAM } from './AddOwnerForm'
import Review from './Review'
import selector, { type SelectorProps } from './selector'
@ -58,7 +58,7 @@ class AddOwner extends React.Component<Props, State> {
safe, threshold, userAddress, fetchTransactions,
} = this.props
await addOwner(values, safe, threshold, userAddress)
fetchTransactions()
fetchTransactions(safe.get('address'))
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
userAddress: userAccountSelector,

View File

@ -2,9 +2,9 @@
import * as React from 'react'
import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { createTransaction } from '~/wallets/createTransactions'
import { getEditDailyLimitData, getDailyLimitAddress } from '~/routes/safe/component/Withdraw/withdraw'
import { type Safe } from '~/routes/safe/store/model/safe'
import { createTransaction } from '~/logic/safe/safeFrontendOperations'
import { getEditDailyLimitData, getDailyLimitAddress } from '~/logic/contracts/dailyLimitContracts'
import EditDailyLimitForm, { EDIT_DAILY_LIMIT_PARAM } from './EditDailyLimitForm'
import selector, { type SelectorProps } from './selector'
import actions, { type Actions } from './actions'
@ -40,7 +40,7 @@ class EditDailyLimit extends React.PureComponent<Props, State> {
const to = await getDailyLimitAddress(safeAddress)
const nonce = Date.now()
await createTransaction(safe, `Change Safe's daily limit to ${newDailyLimit} [${nonce}]`, to, 0, nonce, userAddress, data)
await this.props.fetchTransactions()
await this.props.fetchTransactions(safeAddress)
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
userAddress: userAccountSelector,

View File

@ -3,7 +3,7 @@ import * as React from 'react'
import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { type Safe } from '~/routes/safe/store/model/safe'
import { getSafeEthereumInstance, createTransaction } from '~/wallets/createTransactions'
import { getSafeEthereumInstance, createTransaction } from '~/logic/safe/safeFrontendOperations'
import RemoveOwnerForm, { DECREASE_PARAM } from './RemoveOwnerForm'
import Review from './Review'
import selector, { type SelectorProps } from './selector'
@ -65,7 +65,7 @@ class RemoveOwner extends React.Component<Props, State> {
safe, threshold, executor, fetchTransactions, userToRemove, name,
} = this.props
await removeOwner(values, safe, threshold, userToRemove, name, executor)
fetchTransactions()
fetchTransactions(safe.get('address'))
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })

View File

@ -1,18 +1,14 @@
// @flow
import { List } from 'immutable'
import { createStructuredSelector, createSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
const pendingTransactionsSelector = createSelector(
safeTransactionsSelector,
(transactions: List<Transaction>) =>
transactions.findEntry((transaction: Transaction) => {
const txHash = transaction.get('tx')
return txHash === '' || txHash === undefined
}) !== undefined,
transactions.findEntry((tx: Transaction) => tx.get('isExecuted')),
)
export type SelectorProps = {

View File

@ -17,7 +17,7 @@ import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import { type OwnerProps } from '~/routes/safe/store/model/owner'
import { type WithStyles } from '~/theme/mui'
import { sameAddress } from '~/wallets/ethAddresses'
import { sameAddress } from '~/logic/wallets/ethAddresses'
const styles = {
nested: {

View File

@ -77,7 +77,7 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
onListTransactions = () => {
const { safe } = this.props
this.setState({ component: <Transactions safeName={safe.get('name')} safeAddress={safe.get('address')} /> })
this.setState({ component: <Transactions threshold={safe.get('threshold')} safeName={safe.get('name')} safeAddress={safe.get('address')} /> })
}
onEditThreshold = () => {

View File

@ -7,10 +7,10 @@ import { sleep } from '~/utils/timer'
import { type Safe } from '~/routes/safe/store/model/safe'
import { getStandardTokenContract } from '~/routes/tokens/store/actions/fetchTokens'
import { type Token } from '~/routes/tokens/store/model/token'
import { createTransaction } from '~/wallets/createTransactions'
import { EMPTY_DATA } from '~/wallets/ethTransactions'
import { toNative } from '~/wallets/tokens'
import { isEther } from '~/utils/tokens'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { toNative } from '~/logic/wallets/tokens'
import { createTransaction } from '~/logic/safe/safeFrontendOperations'
import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector'
import SendTokenForm, { TKN_DESTINATION_PARAM, TKN_VALUE_PARAM } from './SendTokenForm'
@ -67,7 +67,7 @@ class SendToken extends React.Component<Props, State> {
await processTokenTransfer(safe, token, destination, amount, userAddress)
await sleep(1500)
this.props.fetchTransactions()
this.props.fetchTransactions(safe.get('address'))
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
userAddress: userAccountSelector,

View File

@ -2,7 +2,7 @@
import * as React from 'react'
import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { getSafeEthereumInstance, createTransaction } from '~/wallets/createTransactions'
import { getSafeEthereumInstance, createTransaction } from '~/logic/safe/safeFrontendOperations'
import { type Safe } from '~/routes/safe/store/model/safe'
import ThresholdForm, { THRESHOLD_PARAM } from './ThresholdForm'
import selector, { type SelectorProps } from './selector'
@ -34,11 +34,12 @@ class Threshold extends React.PureComponent<Props, State> {
try {
const { safe, userAddress } = this.props // , fetchThreshold } = this.props
const newThreshold = values[THRESHOLD_PARAM]
const gnosisSafe = await getSafeEthereumInstance(safe.get('address'))
const safeAddress = safe.get('address')
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const nonce = Date.now()
const data = gnosisSafe.contract.changeThreshold.getData(newThreshold)
await createTransaction(safe, `Change Safe's threshold [${nonce}]`, safe.get('address'), 0, nonce, userAddress, data)
await this.props.fetchTransactions()
await createTransaction(safe, `Change Safe's threshold [${nonce}]`, safeAddress, 0, nonce, userAddress, data)
await this.props.fetchTransactions(safeAddress)
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
userAddress: userAccountSelector,

View File

@ -27,10 +27,11 @@ type Props = Open & WithStyles & {
threshold: number,
}
const GnoConfirmation = ({ owner, status, hash }: ConfirmationProps) => {
const GnoConfirmation = ({ owner, type, hash }: ConfirmationProps) => {
const address = owner.get('address')
const text = status ? 'Confirmed' : 'Not confirmed'
const hashText = status ? `Confirmation hash: ${hash}` : undefined
const confirmed = type === 'confirmation'
const text = confirmed ? 'Confirmed' : 'Not confirmed'
const hashText = confirmed ? `Confirmation hash: ${hash}` : undefined
return (
<React.Fragment>
@ -70,7 +71,7 @@ const Confirmaitons = openHoc(({
<GnoConfirmation
key={confirmation.get('owner').get('address')}
owner={confirmation.get('owner')}
status={confirmation.get('status')}
type={confirmation.get('type')}
hash={confirmation.get('hash')}
/>
))}

View File

@ -19,13 +19,14 @@ import Collapsed from '~/routes/safe/component/Transactions/Collapsed'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import Hairline from '~/components/layout/Hairline/index'
import Button from '~/components/layout/Button'
import { sameAddress } from '~/wallets/ethAddresses'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
import selector, { type SelectorProps } from './selector'
type Props = Open & SelectorProps & {
transaction: Transaction,
safeName: string,
threshold: number,
onProcessTx: (tx: Transaction, alreadyConfirmed: number) => void,
}
@ -35,15 +36,14 @@ class GnoTransaction extends React.PureComponent<Props, {}> {
onProccesClick = () => this.props.onProcessTx(this.props.transaction, this.props.confirmed)
hasConfirmed = (userAddress: string, confirmations: List<Confirmation>): boolean =>
confirmations.filter((conf: Confirmation) => sameAddress(userAddress, conf.get('owner').get('address')) && conf.get('status')).count() > 0
confirmations.filter((conf: Confirmation) => sameAddress(userAddress, conf.get('owner').get('address')) && conf.get('type') === 'confirmation').count() > 0
render() {
const {
open, toggle, transaction, confirmed, safeName, userAddress,
open, toggle, transaction, confirmed, safeName, userAddress, executionHash, threshold,
} = this.props
const txHash = transaction.get('tx')
const confirmationText = txHash ? 'Already executed' : `${confirmed} of the ${transaction.get('threshold')} confirmations needed`
const confirmationText = executionHash ? 'Already executed' : `${confirmed} of the ${threshold} confirmations needed`
const userConfirmed = this.hasConfirmed(userAddress, transaction.get('confirmations'))
return (
@ -72,19 +72,19 @@ class GnoTransaction extends React.PureComponent<Props, {}> {
</Row>
<Row>
<ListItem>
{ txHash &&
{ executionHash &&
<React.Fragment>
<Avatar><CompareArrows /></Avatar>
<ListItemText cut primary="Transaction Hash" secondary={txHash} />
<ListItemText cut primary="Transaction Hash" secondary={executionHash} />
</React.Fragment>
}
{ !txHash && userConfirmed &&
{ !executionHash && userConfirmed &&
<React.Fragment>
<Avatar><CompareArrows /></Avatar>
<ListItemText cut primary="Confirmed" secondary="Waiting for the rest of confirmations" />
</React.Fragment>
}
{ !txHash && !userConfirmed &&
{ !executionHash && !userConfirmed &&
<Button
variant="raised"
color="primary"
@ -100,7 +100,7 @@ class GnoTransaction extends React.PureComponent<Props, {}> {
safeName={safeName}
confirmations={transaction.get('confirmations')}
destination={transaction.get('destination')}
threshold={transaction.get('threshold')}
threshold={threshold}
/> }
<Hairline />
</React.Fragment>

View File

@ -1,14 +1,34 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { confirmationsTransactionSelector } from '~/routes/safe/store/selectors/index'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { type GlobalState } from '~/store'
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
export type SelectorProps = {
confirmed: confirmationsTransactionSelector,
userAddress: userAccountSelector,
executionHash: string,
}
type TxProps = {
transaction: Transaction,
}
const transactionHashSector = (state: GlobalState, props: TxProps) => {
if (!props.transaction) {
return undefined
}
const confirmations = props.transaction.get('confirmations')
const executedConf = confirmations.find((conf: Confirmation) => conf.get('type') === 'execution')
return executedConf ? executedConf.get('hash') : undefined
}
export default createStructuredSelector({
executionHash: transactionHashSector,
confirmed: confirmationsTransactionSelector,
userAddress: userAccountSelector,
})

View File

@ -4,33 +4,48 @@ import { connect } from 'react-redux'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import NoTransactions from '~/routes/safe/component/Transactions/NoTransactions'
import GnoTransaction from '~/routes/safe/component/Transactions/Transaction'
import { processTransaction } from './processTransactions'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
import { processTransaction } from '~/logic/safe/safeFrontendOperations'
import selector, { type SelectorProps } from './selector'
import actions, { type Actions } from './actions'
type Props = SelectorProps & Actions & {
safeName: string,
safeAddress: string,
threshold: number,
}
class Transactions extends React.Component<Props, {}> {
onProcessTx = async (tx: Transaction, alreadyConfirmed: number) => {
const {
fetchTransactions, safeAddress, userAddress,
fetchTransactions, safeAddress, userAddress, threshold,
} = this.props
await processTransaction(safeAddress, tx, alreadyConfirmed, userAddress)
fetchTransactions()
const confirmations = tx.get('confirmations')
const userHasAlreadyConfirmed = confirmations.filter((confirmation: Confirmation) => {
const ownerAddress = confirmation.get('owner').get('address')
const samePerson = sameAddress(ownerAddress, userAddress)
return samePerson && confirmation.get('type') === 'confirmation'
}).count() > 0
if (userHasAlreadyConfirmed) {
throw new Error('Owner has already confirmed this transaction')
}
await processTransaction(safeAddress, tx, alreadyConfirmed, userAddress, threshold)
fetchTransactions(safeAddress)
}
render() {
const { transactions, safeName } = this.props
const { transactions, safeName, threshold } = this.props
const hasTransactions = transactions.count() > 0
return (
<React.Fragment>
{ hasTransactions
? transactions.map((tx: Transaction) => <GnoTransaction key={tx.get('nonce')} safeName={safeName} onProcessTx={this.onProcessTx} transaction={tx} />)
? transactions.map((tx: Transaction) => <GnoTransaction key={tx.get('nonce')} safeName={safeName} onProcessTx={this.onProcessTx} transaction={tx} threshold={threshold} />)
: <NoTransactions />
}
</React.Fragment>

View File

@ -1,146 +0,0 @@
// @flow
import { List } from 'immutable'
import { type Owner } from '~/routes/safe/store/model/owner'
import { load, TX_KEY } from '~/utils/localStorage'
import { type Confirmation, makeConfirmation } from '~/routes/safe/store/model/confirmation'
import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction'
import { getGnosisSafeContract } from '~/wallets/safeContracts'
import { getWeb3 } from '~/wallets/getWeb3'
import { sameAddress } from '~/wallets/ethAddresses'
import { EXECUTED_CONFIRMATION_HASH } from '~/wallets/createTransactions'
import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions'
export const updateTransaction = (
name: string,
nonce: number,
destination: string,
value: number,
creator: string,
confirmations: List<Confirmation>,
tx: string,
safeAddress: string,
safeThreshold: number,
data: string,
) => {
const transaction: Transaction = makeTransaction({
name, nonce, value, confirmations, destination, threshold: safeThreshold, tx, data,
})
const safeTransactions = load(TX_KEY) || {}
const transactions = safeTransactions[safeAddress]
const txsRecord = transactions ? List(transactions) : List([])
const index = txsRecord.findIndex((trans: TransactionProps) => trans.nonce === nonce)
safeTransactions[safeAddress] = txsRecord.remove(index).push(transaction)
localStorage.setItem(TX_KEY, JSON.stringify(safeTransactions))
}
const getOperation = () => 0
const execTransaction = async (
gnosisSafe: any,
destination: string,
txValue: number,
nonce: number,
executor: string,
data: string,
) => {
const CALL = getOperation()
const web3 = getWeb3()
const valueInWei = web3.toWei(txValue, 'ether')
const txData = await gnosisSafe.contract.execTransactionIfApproved.getData(destination, valueInWei, data, CALL, nonce)
const owners = await gnosisSafe.getOwners()
const gas = await calculateGasOf(txData, executor, gnosisSafe.address) + (17000 * owners.length)
const gasPrice = await calculateGasPrice()
return gnosisSafe
.execTransactionIfApproved(destination, valueInWei, data, CALL, nonce, { from: executor, gas, gasPrice })
}
const execConfirmation = async (
gnosisSafe: any,
txDestination: string,
txValue: number,
nonce: number,
executor: string,
data: string,
) => {
const CALL = getOperation()
const web3 = getWeb3()
const valueInWei = web3.toWei(txValue, 'ether')
const txData = await gnosisSafe.contract
.approveTransactionWithParameters.getData(txDestination, valueInWei, data, CALL, nonce)
const gas = await calculateGasOf(txData, executor, gnosisSafe.address)
const gasPrice = await calculateGasPrice()
return gnosisSafe
.approveTransactionWithParameters(txDestination, valueInWei, data, CALL, nonce, { from: executor, gas, gasPrice })
}
const updateConfirmations = (confirmations: List<Confirmation>, userAddress: string, txHash: string) =>
confirmations.map((confirmation: Confirmation) => {
const owner: Owner = confirmation.get('owner')
const samePerson = sameAddress(owner.get('address'), userAddress)
const status: boolean = samePerson ? true : confirmation.get('status')
const hash: string = samePerson ? txHash : confirmation.get('hash')
return makeConfirmation({ owner, status, hash })
})
export const processTransaction = async (
safeAddress: string,
tx: Transaction,
alreadyConfirmed: number,
userAddress: string,
) => {
const web3 = getWeb3()
const GnosisSafe = await getGnosisSafeContract(web3)
const gnosisSafe = GnosisSafe.at(safeAddress)
const confirmations = tx.get('confirmations')
const userHasAlreadyConfirmed = confirmations.filter((confirmation: Confirmation) => {
const ownerAddress = confirmation.get('owner').get('address')
const samePerson = sameAddress(ownerAddress, userAddress)
return samePerson && confirmation.get('status')
}).count() > 0
if (userHasAlreadyConfirmed) {
throw new Error('Owner has already confirmed this transaction')
}
const threshold = tx.get('threshold')
const thresholdReached = threshold === alreadyConfirmed + 1
const nonce = tx.get('nonce')
const txName = tx.get('name')
const txValue = tx.get('value')
const txDestination = tx.get('destination')
const data = tx.get('data')
const txHash = thresholdReached
? await execTransaction(gnosisSafe, txDestination, txValue, nonce, userAddress, data)
: await execConfirmation(gnosisSafe, txDestination, txValue, nonce, userAddress, data)
checkReceiptStatus(txHash.tx)
const confirmationHash =
thresholdReached ? EXECUTED_CONFIRMATION_HASH : txHash.tx
const executedConfirmations: List<Confirmation> =
updateConfirmations(tx.get('confirmations'), userAddress, confirmationHash)
return updateTransaction(
txName,
nonce,
txDestination,
txValue,
userAddress,
executedConfirmations,
thresholdReached ? txHash.tx : '',
safeAddress,
threshold,
data,
)
}

View File

@ -3,7 +3,7 @@ import { List } from 'immutable'
import { createStructuredSelector } from 'reselect'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
transactions: List<Transaction>,

View File

@ -5,7 +5,7 @@ import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'
import Paragraph from '~/components/layout/Paragraph'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/WithdrawForm'
type FormProps = {
values: Object,

View File

@ -5,9 +5,10 @@ import TextField from '~/components/forms/TextField'
import { composeValidators, inLimit, mustBeFloat, required, greaterThan, mustBeEthereumAddress } from '~/components/forms/validator'
import Block from '~/components/layout/Block'
import Heading from '~/components/layout/Heading'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
export const DESTINATION_PARAM = 'destination'
export const VALUE_PARAM = 'ether'
export const safeFieldsValidation = (values: Object) => {
const errors = {}

View File

@ -4,8 +4,8 @@ import { connect } from 'react-redux'
import Stepper from '~/components/Stepper'
import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
import { type Safe } from '~/routes/safe/store/model/safe'
import { withdraw } from '~/logic/safe/safeFrontendOperations'
import selector, { type SelectorProps } from './selector'
import withdraw from './withdraw'
import WithdrawForm from './WithdrawForm'
import Review from './Review'
import actions, { type Actions } from './actions'
@ -34,7 +34,7 @@ class Withdraw extends React.Component<Props, State> {
try {
const { safe, userAddress, fetchTransactions } = this.props
await withdraw(values, safe, userAddress)
fetchTransactions()
fetchTransactions(safe.get('address'))
this.setState({ done: true })
} catch (error) {

View File

@ -1,6 +1,6 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { userAccountSelector } from '~/logic/wallets/store/selectors'
export type SelectorProps = {
userAddress: userAccountSelector,

View File

@ -1,78 +0,0 @@
// @flow
import { List } from 'immutable'
import { getWeb3 } from '~/wallets/getWeb3'
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts'
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
import { checkReceiptStatus, calculateGasOf, calculateGasPrice, EMPTY_DATA } from '~/wallets/ethTransactions'
import { type Safe } from '~/routes/safe/store/model/safe'
import { buildExecutedConfirmationFrom, storeTransaction } from '~/wallets/createTransactions'
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
export const LIMIT_POSITION = 0
export const SPENT_TODAY_POS = 1
export const DESTINATION_PARAM = 'destination'
export const VALUE_PARAM = 'ether'
const getDailyLimitModuleFrom = async (safeAddress) => {
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)
}
const withdraw = async (values: Object, safe: Safe, userAccount: string): Promise<void> => {
const web3 = getWeb3()
const safeAddress = safe.get('address')
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const destination = values[DESTINATION_PARAM]
const valueInEth = values[VALUE_PARAM]
const value = web3.toWei(valueInEth, 'ether')
const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, destination, value)
const gas = await calculateGasOf(dailyLimitData, userAccount, dailyLimitModule.address)
const gasPrice = await calculateGasPrice()
const txHash = await dailyLimitModule.executeDailyLimit(0, destination, value, { from: userAccount, gas, gasPrice })
checkReceiptStatus(txHash.tx)
const nonce = Date.now()
const executedConfirmations: List<Confirmation> = buildExecutedConfirmationFrom(safe.get('owners'), userAccount)
return storeTransaction(`Withdraw movement of ${valueInEth}`, nonce, destination, valueInEth, userAccount, executedConfirmations, txHash.tx, safeAddress, safe.get('threshold'), EMPTY_DATA)
}
export default withdraw

View File

@ -2,11 +2,11 @@
import { List } from 'immutable'
import { createSelector, createStructuredSelector, type Selector } from 'reselect'
import { safeSelector, type RouterProps, type SafeSelectorProps } from '~/routes/safe/store/selectors'
import { providerNameSelector, userAccountSelector } from '~/wallets/store/selectors/index'
import { providerNameSelector, userAccountSelector } from '~/logic/wallets/store/selectors'
import { type Safe } from '~/routes/safe/store/model/safe'
import { type Owner } from '~/routes/safe/store/model/owner'
import { type GlobalState } from '~/store/index'
import { sameAddress } from '~/wallets/ethAddresses'
import { type GlobalState } from '~/store'
import { sameAddress } from '~/logic/wallets/ethAddresses'
import { activeTokensSelector } from '~/routes/tokens/store/selectors'
import { type Token } from '~/routes/tokens/store/model/token'

View File

@ -5,10 +5,10 @@ import { type GlobalState } from '~/store/index'
import { makeOwner } from '~/routes/safe/store/model/owner'
import { type SafeProps, type Safe, makeSafe } from '~/routes/safe/store/model/safe'
import { makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw'
import { getGnosisSafeInstanceAt } from '~/wallets/safeContracts'
import updateSafe from '~/routes/safe/store/actions/updateSafe'
import { getOwners } from '~/utils/localStorage'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { getDailyLimitFrom } from '~/logic/contracts/dailyLimitContracts'
const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>) => (
safeOwners.map((ownerAddress: string) => {

View File

@ -3,34 +3,70 @@ import { List, Map } from 'immutable'
import type { Dispatch as ReduxDispatch } from 'redux'
import { type GlobalState } from '~/store/index'
import { makeOwner } from '~/routes/safe/store/model/owner'
import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction'
import { load, TX_KEY } from '~/utils/localStorage'
import { type Confirmation, type ConfirmationProps, makeConfirmation } from '~/routes/safe/store/model/confirmation'
import { makeTransaction, type Transaction } from '~/routes/safe/store/model/transaction'
import { makeConfirmation } from '~/routes/safe/store/model/confirmation'
import { loadSafeSubjects } from '~/utils/localStorage/transactions'
import { buildTxServiceUrlFrom, type TxServiceType } from '~/logic/safe/safeTxHistory'
import { enhancedFetch } from '~/utils/fetch'
import { getOwners } from '~/utils/localStorage'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import addTransactions from './addTransactions'
export const loadSafeTransactions = () => {
const safes = load(TX_KEY) || {}
return Map().withMutations((map: Map<string, List<Confirmation>>) =>
Object.keys(safes).map((safe: string) => {
const safeTxs = safes[safe]
const safeTxsRecord = safeTxs.map((tx: TransactionProps) => {
const { confirmations } = tx
const txRecord = makeTransaction({
...tx,
confirmations: List(confirmations.map((conf: ConfirmationProps) =>
makeConfirmation({ ...conf, owner: makeOwner(conf.owner) }))),
})
return txRecord
})
return map.set(safe, List(safeTxsRecord))
}))
type ConfirmationServiceModel = {
owner: string,
submissionDate: Date,
type: TxServiceType,
transactionHash: string,
}
export default () => async (dispatch: ReduxDispatch<GlobalState>) => {
const transactions: Map<string, List<Transaction>> = await loadSafeTransactions()
type TxServiceModel = {
to: string,
value: number,
data: string,
operation: number,
nonce: number,
submissionDate: Date,
executionDate: Date,
confirmations: ConfirmationServiceModel[],
isExecuted: boolean,
}
const buildTransactionFrom = (safeAddress: string, tx: TxServiceModel, safeSubjects: Map<string, string>) => {
const name = safeSubjects.get(String(tx.nonce)) || 'Unknown'
const storedOwners = getOwners(safeAddress)
const confirmations = List(tx.confirmations.map((conf: ConfirmationServiceModel) => {
const ownerName = storedOwners.get(conf.owner.toLowerCase()) || 'UNKNOWN'
return makeConfirmation({
owner: makeOwner({ address: conf.owner, name: ownerName }),
type: conf.type,
hash: conf.transactionHash,
})
}))
return makeTransaction({
name,
nonce: tx.nonce,
value: Number(tx.value),
confirmations,
destination: tx.to,
data: tx.data ? tx.data : EMPTY_DATA,
isExecuted: tx.isExecuted,
})
}
export const loadSafeTransactions = async (safeAddress: string) => {
const url = buildTxServiceUrlFrom(safeAddress)
const response = await enhancedFetch(url, 'Error fetching txs information')
const transactions: TxServiceModel[] = response.results
const safeSubjects = loadSafeSubjects(safeAddress)
const txsRecord = transactions.map((tx: TxServiceModel) => buildTransactionFrom(safeAddress, tx, safeSubjects))
return Map().set(safeAddress, List(txsRecord))
}
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
const transactions: Map<string, List<Transaction>> = await loadSafeTransactions(safeAddress)
return dispatch(addTransactions(transactions))
}

View File

@ -2,16 +2,17 @@
import { Record } from 'immutable'
import type { RecordFactory, RecordOf } from 'immutable'
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
import { type TxServiceType } from '~/logic/safe/safeTxHistory'
export type ConfirmationProps = {
owner: Owner,
status: boolean, // false: not confirmed, true: confirmed
type: TxServiceType,
hash: string,
}
export const makeConfirmation: RecordFactory<ConfirmationProps> = Record({
owner: makeOwner(),
status: false,
type: 'initialised',
hash: '',
})

View File

@ -7,11 +7,10 @@ export type TransactionProps = {
name: string,
nonce: number,
value: number,
threshold: number,
confirmations: List<Confirmation>,
destination: string,
tx: string,
data: string,
isExecuted: boolean,
}
export const makeTransaction: RecordFactory<TransactionProps> = Record({
@ -20,9 +19,8 @@ export const makeTransaction: RecordFactory<TransactionProps> = Record({
value: 0,
confirmations: List([]),
destination: '',
tx: '',
threshold: 0,
data: '',
isExecuted: false,
})
export type Transaction = RecordOf<TransactionProps>

View File

@ -3,14 +3,11 @@ import { List, Map } from 'immutable'
import { handleActions, type ActionType } from 'redux-actions'
import addTransactions, { ADD_TRANSACTIONS } from '~/routes/safe/store/actions/addTransactions'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { loadSafeTransactions } from '~/routes/safe/store/actions/fetchTransactions'
export const TRANSACTIONS_REDUCER_ID = 'transactions'
export type State = Map<string, List<Transaction>>
export const transactionsInitialState = () => loadSafeTransactions()
export default handleActions({
[ADD_TRANSACTIONS]: (state: State, action: ActionType<typeof addTransactions>): State =>
action.payload,

View File

@ -58,7 +58,7 @@ export const confirmationsTransactionSelector: Selector<GlobalState, Transaction
return 0
}
return confirmations.filter(((confirmation: Confirmation) => confirmation.get('status'))).count()
return confirmations.filter(((confirmation: Confirmation) => confirmation.get('type') === 'confirmation')).count()
},
)

View File

@ -8,12 +8,13 @@ import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation
import Open from '~/routes/open/container/Open'
import { history, type GlobalState } from '~/store'
import { sleep } from '~/utils/timer'
import { getProviderInfo, getWeb3 } from '~/wallets/getWeb3'
import addProvider from '~/wallets/store/actions/addProvider'
import { makeProvider } from '~/wallets/store/model/provider'
import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
import { getProviderInfo, getWeb3 } from '~/logic/wallets/getWeb3'
import addProvider from '~/logic/wallets/store/actions/addProvider'
import { makeProvider } from '~/logic/wallets/store/model/provider'
import { promisify } from '~/utils/promisify'
import { type Safe } from '~/routes/safe/store/model/safe'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/WithdrawForm'
import { withdraw } from '~/logic/safe/safeFrontendOperations'
export const renderSafe = async (localStore: Store<GlobalState>) => {
const provider = await getProviderInfo()

Some files were not shown because too many files have changed in this diff Show More