commit 13a81def57f738b4344304e271b5a5397c5307c2
parent 4cf33d8cfd5510e30346fd7e805020b201e52a20
Author: nolash <dev@holbrook.no>
Date: Tue, 15 Dec 2020 09:02:15 +0100
Rename contract files, external requirements files
Diffstat:
11 files changed, 110 insertions(+), 13 deletions(-)
diff --git a/python/MANIFEST.in b/python/MANIFEST.in
@@ -1 +1 @@
-include **/*.abi.json
+include **/data/*Approval*.json **/data/*Approval*.bin
diff --git a/python/erc20_approval_escrow/__init__.py b/python/erc20_approval_escrow/__init__.py
@@ -0,0 +1 @@
+from .approval import TransferApproval
diff --git a/python/erc20_approval_escrow/data/TransferApproval.bin b/python/erc20_approval_escrow/data/TransferApproval.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610f54380380610f548339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186602082028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019060200280838360005b838110156100bd5780820151818401526020810190506100a2565b5050505090500160405250505060005b815181101561014e576001600260008484815181106100e857fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806001019150506100cd565b50600160008190555050610ded806101676000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630a144391146100675780636c355091146100c157806381d12c5814610143578063b8adaa11146101e3578063f6d713dd14610227578063fe0d94c114610245575b600080fd5b6100a96004803603602081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610289565b60405180821515815260200191505060405180910390f35b61012d600480360360608110156100d757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506102a9565b6040518082815260200191505060405180910390f35b61016f6004803603602081101561015957600080fd5b81019080803590602001909291905050506104b7565b604051808681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019550505050505060405180910390f35b61020f600480360360208110156101f957600080fd5b810190808035906020019092919050505061054d565b60405180821515815260200191505060405180910390f35b61022f61097f565b6040518082815260200191505060405180910390f35b6102716004803603602081101561025b57600080fd5b8101908080359060200190929190505050610985565b60405180821515815260200191505060405180910390f35b60026020528060005260406000206000915054906101000a900460ff1681565b600080600160008054815260200190815260200160002090506000548160000181905550848160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550338160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082816004018190555060008081548092919060010191905055508060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fb609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c84600401548560000154604051808381526020018281526020019250505060405180910390a480600001549150509392505050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040154905085565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4e4f5f4143434553530000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600160008481526020019081526020016000209050600081600001541161069f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f4552525f494e56414c49445f524551554553540000000000000000000000000081525060200191505060405180910390fd5b600060608260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560040154604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106108275780518252602082019150602081019050602083039250610804565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610889576040519150601f19603f3d011682016040523d82523d6000602084013e61088e565b606091505b50915091508161089a57fe5b7f607c56ea76669e46679e89091227c1a3f91841a4cf7588d5a6c84555fb59fdfd83600001546040518082815260200191505060405180910390a160016000846000015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560048201600090555050819350505050919050565b60005481565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4e4f5f4143434553530000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001600084815260200190815260200160002090506000816000015411610ad7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f4552525f494e56414c49445f524551554553540000000000000000000000000081525060200191505060405180910390fd5b600060608260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560040154604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610c5f5780518252602082019150602081019050602083039250610c3c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610cc1576040519150601f19603f3d011682016040523d82523d6000602084013e610cc6565b606091505b509150915081610cd257fe5b7fa445ec1ee84565906bc8646dcb62f6d1a75fc7a782a03e72220fb97f60ba89ab83600001546040518082815260200191505060405180910390a160016000846000015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160009055505081935050505091905056fea264697066735822122027854a054b06dcbba643ec3336be99a459dab354eee6bab60354f36d6e9f233464736f6c63430007050033
+\ No newline at end of file
diff --git a/python/erc20_approval_escrow/data/TransferApproval.json b/python/erc20_approval_escrow/data/TransferApproval.json
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address[]","name":"_approvers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"serial","type":"uint256"}],"name":"NewExecution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"serial","type":"uint256"}],"name":"NewRejection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"NewRequest","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"reject","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"request","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"uint256","name":"serial","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"serial","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
diff --git a/python/requirements.txt b/python/requirements.txt
@@ -0,0 +1 @@
+web3==5.12.2
diff --git a/python/setup.cfg b/python/setup.cfg
@@ -26,21 +26,11 @@ python_requires = >= 3.6
packages =
erc20_approval_escrow
erc20_approval_escrow.runnable
-install_requires =
- web3==5.12.2
-tests_require =
- eth-tester==0.5.0b2
- py-evm==0.3.0a20
-
-[options.extras_require]
-testing =
- eth-tester==0.5.0b2
- py-evm==0.3.0a20
[options.package_data]
* =
- data/ERC20ApprovalEscrow.abi.json
- data/ERC20ApprovalEscrow.bin
+ data/TransferApproval.json
+ data/TransferApproval.bin
[options.entry_points]
console_scripts =
diff --git a/python/setup.py b/python/setup.py
@@ -1,4 +1,26 @@
from setuptools import setup
+import configparser
+
+
+requirements = []
+f = open('requirements.txt', 'r')
+while True:
+ l = f.readline()
+ if l == '':
+ break
+ requirements.append(l.rstrip())
+f.close()
+
+test_requirements = []
+f = open('test_requirements.txt', 'r')
+while True:
+ l = f.readline()
+ if l == '':
+ break
+ test_requirements.append(l.rstrip())
+f.close()
setup(
+ install_requires=requirements,
+ tests_require=test_requirements,
)
diff --git a/python/test_requirements.txt b/python/test_requirements.txt
@@ -0,0 +1,2 @@
+eth-tester==0.5.0b2
+py-evm==0.3.0a20
diff --git a/solidity/TransferApproval.bin b/solidity/TransferApproval.bin
@@ -0,0 +1 @@
+608060405234801561001057600080fd5b50604051610f54380380610f548339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186602082028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019060200280838360005b838110156100bd5780820151818401526020810190506100a2565b5050505090500160405250505060005b815181101561014e576001600260008484815181106100e857fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806001019150506100cd565b50600160008190555050610ded806101676000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630a144391146100675780636c355091146100c157806381d12c5814610143578063b8adaa11146101e3578063f6d713dd14610227578063fe0d94c114610245575b600080fd5b6100a96004803603602081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610289565b60405180821515815260200191505060405180910390f35b61012d600480360360608110156100d757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506102a9565b6040518082815260200191505060405180910390f35b61016f6004803603602081101561015957600080fd5b81019080803590602001909291905050506104b7565b604051808681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019550505050505060405180910390f35b61020f600480360360208110156101f957600080fd5b810190808035906020019092919050505061054d565b60405180821515815260200191505060405180910390f35b61022f61097f565b6040518082815260200191505060405180910390f35b6102716004803603602081101561025b57600080fd5b8101908080359060200190929190505050610985565b60405180821515815260200191505060405180910390f35b60026020528060005260406000206000915054906101000a900460ff1681565b600080600160008054815260200190815260200160002090506000548160000181905550848160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550338160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082816004018190555060008081548092919060010191905055508060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fb609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c84600401548560000154604051808381526020018281526020019250505060405180910390a480600001549150509392505050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040154905085565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661060e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4e4f5f4143434553530000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600160008481526020019081526020016000209050600081600001541161069f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f4552525f494e56414c49445f524551554553540000000000000000000000000081525060200191505060405180910390fd5b600060608260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560040154604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106108275780518252602082019150602081019050602083039250610804565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610889576040519150601f19603f3d011682016040523d82523d6000602084013e61088e565b606091505b50915091508161089a57fe5b7f607c56ea76669e46679e89091227c1a3f91841a4cf7588d5a6c84555fb59fdfd83600001546040518082815260200191505060405180910390a160016000846000015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560048201600090555050819350505050919050565b60005481565b6000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4e4f5f4143434553530000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001600084815260200190815260200160002090506000816000015411610ad7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f4552525f494e56414c49445f524551554553540000000000000000000000000081525060200191505060405180910390fd5b600060608260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168360010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168560040154604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310610c5f5780518252602082019150602081019050602083039250610c3c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610cc1576040519150601f19603f3d011682016040523d82523d6000602084013e610cc6565b606091505b509150915081610cd257fe5b7fa445ec1ee84565906bc8646dcb62f6d1a75fc7a782a03e72220fb97f60ba89ab83600001546040518082815260200191505060405180910390a160016000846000015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160009055505081935050505091905056fea264697066735822122027854a054b06dcbba643ec3336be99a459dab354eee6bab60354f36d6e9f233464736f6c63430007050033
+\ No newline at end of file
diff --git a/solidity/TransferApproval.json b/solidity/TransferApproval.json
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"address[]","name":"_approvers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"serial","type":"uint256"}],"name":"NewExecution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"serial","type":"uint256"}],"name":"NewRejection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"NewRequest","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_serial","type":"uint256"}],"name":"reject","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"request","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"uint256","name":"serial","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"serial","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
diff --git a/solidity/TransferApproval.sol b/solidity/TransferApproval.sol
@@ -0,0 +1,75 @@
+pragma solidity >=0.6.12;
+
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+contract ERC20ApprovalEscrow {
+ struct Transaction {
+ uint256 serial;
+ address sender;
+ address recipient;
+ address token;
+ uint256 value;
+ }
+ uint256 public serial;
+ mapping(uint256 => Transaction) public requests;
+ mapping(address => bool) public approvers;
+
+ event NewRequest(address indexed _sender, address indexed _recipient, address indexed _token, uint256 _value, uint256 _serial);
+ event NewExecution(uint256 serial);
+ event NewRejection(uint256 serial);
+
+ constructor(address[] memory _approvers) public {
+ for (uint i = 0; i < _approvers.length; i++) {
+ approvers[_approvers[i]] = true;
+ }
+ serial = 1;
+ }
+
+ function request(address _recipient, address _token, uint256 _value) public returns (uint256) {
+ Transaction storage txx = requests[serial];
+
+ txx.serial = serial;
+ txx.recipient = _recipient;
+ txx.sender = msg.sender;
+ txx.token = _token;
+ txx.value = _value;
+
+ serial++;
+
+ emit NewRequest(txx.sender, txx.recipient, txx.token, txx.value, txx.serial);
+
+ return txx.serial;
+ }
+
+ function execute(uint256 _serial) public returns (bool) {
+ require(approvers[msg.sender], 'ERR_NO_ACCESS');
+
+ Transaction storage txx = requests[_serial];
+ require(txx.serial > 0, 'ERR_INVALID_REQUEST');
+
+ (bool success, bytes memory _) = txx.token.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", txx.sender, txx.recipient, txx.value));
+ assert(success);
+
+ emit NewExecution(txx.serial);
+
+ delete requests[txx.serial];
+
+ return success;
+ }
+
+ function reject(uint256 _serial) public returns (bool) {
+ require(approvers[msg.sender], 'ERR_NO_ACCESS');
+
+ Transaction storage txx = requests[_serial];
+ require(txx.serial > 0, 'ERR_INVALID_REQUEST');
+
+ (bool success, bytes memory _) = txx.token.call(abi.encodeWithSignature("transferFrom(address,address,uint256)", txx.sender, txx.sender, txx.value));
+ assert(success);
+
+ emit NewRejection(txx.serial);
+
+ delete requests[txx.serial];
+
+ return success;
+ }
+}