Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.

Commit 94ac948

Browse files
bweickasoong
authored andcommitted
Require successful transfer on external contract
1 parent f04712d commit 94ac948

File tree

5 files changed

+361
-8
lines changed

5 files changed

+361
-8
lines changed

contracts/core/TransferProxy.sol

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pragma solidity 0.4.24;
1818

1919

2020
import { Authorizable } from "../lib/Authorizable.sol";
21-
import { ERC20 } from "zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
2221
import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol";
22+
import { TokenInteract } from "./lib/TokenInteract.sol";
2323

2424

2525
/**
@@ -80,17 +80,25 @@ contract TransferProxy is
8080
onlyAuthorized
8181
{
8282
// Retrieve current balance of token for the vault
83-
uint existingVaultBalance = ERC20(_tokenAddress).balanceOf(vaultAddress);
83+
uint existingVaultBalance = TokenInteract.balanceOf(
84+
_tokenAddress,
85+
vaultAddress
86+
);
8487

8588
// Call specified ERC20 contract to transfer tokens from user to Vault (via proxy).
86-
ERC20(_tokenAddress).transferFrom(
89+
90+
TokenInteract.transferFrom(
91+
_tokenAddress,
8792
_from,
8893
vaultAddress,
8994
_quantity
9095
);
9196

9297
// Verify transfer quantity is reflected in balance
93-
uint newVaultBalance = ERC20(_tokenAddress).balanceOf(vaultAddress);
98+
uint newVaultBalance = TokenInteract.balanceOf(
99+
_tokenAddress,
100+
vaultAddress
101+
);
94102
require(newVaultBalance == existingVaultBalance.add(_quantity));
95103
}
96104
}

contracts/core/Vault.sol

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pragma solidity 0.4.24;
2020
import { Authorizable } from "../lib/Authorizable.sol";
2121
import { ERC20 } from "zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
2222
import { SafeMath } from "zeppelin-solidity/contracts/math/SafeMath.sol";
23+
import { TokenInteract } from "./lib/TokenInteract.sol";
2324

2425

2526
/**
@@ -92,16 +93,23 @@ contract Vault is
9293
isValidDestination(_to)
9394
{
9495
// Retrieve current balance of token for the vault
95-
uint existingVaultBalance = ERC20(_tokenAddress).balanceOf(this);
96+
uint existingVaultBalance = TokenInteract.balanceOf(
97+
_tokenAddress,
98+
this
99+
);
96100

97101
// Call specified ERC20 token contract to transfer tokens from Vault to user
98-
ERC20(_tokenAddress).transfer(
102+
TokenInteract.transfer(
103+
_tokenAddress,
99104
_to,
100105
_quantity
101106
);
102107

103108
// Verify transfer quantity is reflected in balance
104-
uint newVaultBalance = ERC20(_tokenAddress).balanceOf(this);
109+
uint newVaultBalance = TokenInteract.balanceOf(
110+
_tokenAddress,
111+
this
112+
);
105113
require(newVaultBalance == existingVaultBalance.sub(_quantity));
106114
}
107115

@@ -154,7 +162,7 @@ contract Vault is
154162
}
155163

156164
/* ============ Getter Functions ============ */
157-
165+
158166
/*
159167
* Get balance of particular contract for owner.
160168
*
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
Copyright 2018 Set Labs Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
pragma solidity 0.4.24;
15+
16+
import { GeneralERC20 } from "../../lib/GeneralERC20.sol";
17+
18+
19+
/**
20+
* @title TokenInteract
21+
* @author Set Protocol
22+
*
23+
* This library contains functions for interacting wtih ERC20 tokens
24+
*/
25+
library TokenInteract {
26+
function balanceOf(
27+
address token,
28+
address owner
29+
)
30+
internal
31+
view
32+
returns (uint256)
33+
{
34+
return GeneralERC20(token).balanceOf(owner);
35+
}
36+
37+
function transfer(
38+
address token,
39+
address to,
40+
uint256 amount
41+
)
42+
internal
43+
{
44+
45+
GeneralERC20(token).transfer(to, amount);
46+
47+
require(
48+
checkSuccess(),
49+
"TokenInteract#transfer: Transfer failed"
50+
);
51+
}
52+
53+
function transferFrom(
54+
address token,
55+
address from,
56+
address to,
57+
uint256 amount
58+
)
59+
internal
60+
{
61+
62+
GeneralERC20(token).transferFrom(from, to, amount);
63+
64+
require(
65+
checkSuccess(),
66+
"TokenInteract#transferFrom: TransferFrom failed"
67+
);
68+
}
69+
70+
// ============ Private Helper-Functions ============
71+
72+
/**
73+
* Checks the return value of the previous function up to 32 bytes. Returns true if the previous
74+
* function returned 0 bytes or 32 bytes that are not all-zero.
75+
*/
76+
function checkSuccess(
77+
)
78+
private
79+
pure
80+
returns (bool)
81+
{
82+
uint256 returnValue = 0;
83+
84+
/* solium-disable-next-line security/no-inline-assembly */
85+
assembly {
86+
// check number of bytes returned from last function call
87+
switch returndatasize
88+
89+
// no bytes returned: assume success
90+
case 0x0 {
91+
returnValue := 1
92+
}
93+
94+
// 32 bytes returned: check if non-zero
95+
case 0x20 {
96+
// copy 32 bytes into scratch space
97+
returndatacopy(0x0, 0x0, 0x20)
98+
99+
// load those bytes into returnValue
100+
returnValue := mload(0x0)
101+
}
102+
103+
// not sure what was returned: dont mark as success
104+
default { }
105+
}
106+
107+
return returnValue != 0;
108+
}
109+
}

contracts/lib/GeneralERC20.sol

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Copyright 2018 Set Labs Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
pragma solidity 0.4.24;
15+
16+
17+
/**
18+
* @title GeneralERC20
19+
* @author Set Protocol
20+
*
21+
* Interface for using ERC20 Tokens. We have to use a special interface to call ERC20 functions so
22+
* that we dont automatically revert when calling non-compliant tokens that have no return value for
23+
* transfer(), transferFrom(), or approve().
24+
*/
25+
interface GeneralERC20 {
26+
27+
function balanceOf(
28+
address who
29+
)
30+
external
31+
view
32+
returns (uint256);
33+
34+
function transfer(
35+
address to,
36+
uint256 value
37+
)
38+
external;
39+
40+
41+
function transferFrom(
42+
address from,
43+
address to,
44+
uint256 value
45+
)
46+
external;
47+
}

0 commit comments

Comments
 (0)