-
Notifications
You must be signed in to change notification settings - Fork 25
/
ExecutionDelegate.sol
127 lines (112 loc) · 4.04 KB
/
ExecutionDelegate.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
pragma abicoder v2;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import {IExecutionDelegate} from "./interfaces/IExecutionDelegate.sol";
/**
* @title ExecutionDelegate
* @dev Proxy contract to manage user token approvals
*/
contract ExecutionDelegate is IExecutionDelegate, Ownable {
mapping(address => bool) public contracts;
mapping(address => bool) public revokedApproval;
modifier approvedContract() {
require(contracts[msg.sender], "Contract is not approved to make transfers");
_;
}
event ApproveContract(address indexed _contract);
event DenyContract(address indexed _contract);
event RevokeApproval(address indexed user);
event GrantApproval(address indexed user);
/**
* @dev Approve contract to call transfer functions
* @param _contract address of contract to approve
*/
function approveContract(address _contract) onlyOwner external {
contracts[_contract] = true;
emit ApproveContract(_contract);
}
/**
* @dev Revoke approval of contract to call transfer functions
* @param _contract address of contract to revoke approval
*/
function denyContract(address _contract) onlyOwner external {
contracts[_contract] = false;
emit DenyContract(_contract);
}
/**
* @dev Block contract from making transfers on-behalf of a specific user
*/
function revokeApproval() external {
revokedApproval[msg.sender] = true;
emit RevokeApproval(msg.sender);
}
/**
* @dev Allow contract to make transfers on-behalf of a specific user
*/
function grantApproval() external {
revokedApproval[msg.sender] = false;
emit GrantApproval(msg.sender);
}
/**
* @dev Transfer ERC721 token using `transferFrom`
* @param collection address of the collection
* @param from address of the sender
* @param to address of the recipient
* @param tokenId tokenId
*/
function transferERC721Unsafe(address collection, address from, address to, uint256 tokenId)
approvedContract
external
{
require(revokedApproval[from] == false, "User has revoked approval");
IERC721(collection).transferFrom(from, to, tokenId);
}
/**
* @dev Transfer ERC721 token using `safeTransferFrom`
* @param collection address of the collection
* @param from address of the sender
* @param to address of the recipient
* @param tokenId tokenId
*/
function transferERC721(address collection, address from, address to, uint256 tokenId)
approvedContract
external
{
require(revokedApproval[from] == false, "User has revoked approval");
IERC721(collection).safeTransferFrom(from, to, tokenId);
}
/**
* @dev Transfer ERC1155 token using `safeTransferFrom`
* @param collection address of the collection
* @param from address of the sender
* @param to address of the recipient
* @param tokenId tokenId
* @param amount amount
*/
function transferERC1155(address collection, address from, address to, uint256 tokenId, uint256 amount)
approvedContract
external
{
require(revokedApproval[from] == false, "User has revoked approval");
IERC1155(collection).safeTransferFrom(from, to, tokenId, amount, "");
}
/**
* @dev Transfer ERC20 token
* @param token address of the token
* @param from address of the sender
* @param to address of the recipient
* @param amount amount
*/
function transferERC20(address token, address from, address to, uint256 amount)
approvedContract
external
returns (bool)
{
require(revokedApproval[from] == false, "User has revoked approval");
return IERC20(token).transferFrom(from, to, amount);
}
}