Skip to content

Commit 0627946

Browse files
Brechtpddong77
andauthored
[hebao] Optimized memory copies (#1714)
* [hebao] Optimized memory copies * Update AddressUtil.sol * Update AddressUtil.sol * [hebao] Revert to normal calls in smart wallet Co-authored-by: Daniel Wang <[email protected]>
1 parent 20e7ba2 commit 0627946

File tree

9 files changed

+105
-13
lines changed

9 files changed

+105
-13
lines changed

packages/hebao_v1/contracts/base/BaseWallet.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ abstract contract BaseWallet is ReentrancyGuard, Wallet
266266
// This call is introduced to support reentrany check.
267267
// The caller shall NOT have the nonReentrant modifier.
268268
function nonReentrantCall(
269-
uint8 mode,
270-
address target,
271-
uint value,
272-
bytes memory data
269+
uint8 mode,
270+
address target,
271+
uint value,
272+
bytes calldata data
273273
)
274274
private
275275
nonReentrant

packages/hebao_v1/contracts/lib/AddressUtil.sol

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ library AddressUtil
3434
pure
3535
returns (address payable)
3636
{
37-
return address(uint160(addr));
37+
return payable(addr);
3838
}
3939

4040
// Works like address.send but with a customizable gas limit
@@ -68,4 +68,49 @@ library AddressUtil
6868
success = to.sendETH(amount, gasLimit);
6969
require(success, "TRANSFER_FAILURE");
7070
}
71+
72+
// Works like call but is slightly more efficient when data
73+
// needs to be copied from memory to do the call.
74+
function fastCall(
75+
address to,
76+
uint gasLimit,
77+
uint value,
78+
bytes memory data
79+
)
80+
internal
81+
returns (bool success, bytes memory returnData)
82+
{
83+
if (to != address(0)) {
84+
assembly {
85+
// Do the call
86+
success := call(gasLimit, to, value, add(data, 32), mload(data), 0, 0)
87+
// Copy the return data
88+
let size := returndatasize()
89+
returnData := mload(0x40)
90+
mstore(returnData, size)
91+
returndatacopy(add(returnData, 32), 0, size)
92+
// Update free memory pointer
93+
mstore(0x40, add(returnData, add(32, size)))
94+
}
95+
}
96+
}
97+
98+
// Like fastCall, but throws when the call is unsuccessful.
99+
function fastCallAndVerify(
100+
address to,
101+
uint gasLimit,
102+
uint value,
103+
bytes memory data
104+
)
105+
internal
106+
returns (bytes memory returnData)
107+
{
108+
bool success;
109+
(success, returnData) = fastCall(to, gasLimit, value, data);
110+
if (!success) {
111+
assembly {
112+
revert(add(returnData, 32), mload(returnData))
113+
}
114+
}
115+
}
71116
}

packages/hebao_v1/contracts/modules/base/BaseModule.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ abstract contract BaseModule is ReentrancyGuard, Module
184184
address wallet,
185185
address to,
186186
uint value,
187-
bytes memory data
187+
bytes calldata data
188188
)
189189
internal
190190
returns (bytes memory)
@@ -195,7 +195,7 @@ abstract contract BaseModule is ReentrancyGuard, Module
195195
function transactStaticCall(
196196
address wallet,
197197
address to,
198-
bytes memory data
198+
bytes calldata data
199199
)
200200
internal
201201
returns (bytes memory)

packages/hebao_v1/contracts/modules/core/ForwarderModule.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pragma solidity ^0.7.0;
44
pragma experimental ABIEncoderV2;
55

6+
import "../../lib/AddressUtil.sol";
67
import "../../lib/EIP712.sol";
78
import "../../lib/ERC20.sol";
89
import "../../lib/MathUint.sol";
@@ -17,6 +18,7 @@ import "./WalletFactory.sol";
1718
/// @author Daniel Wang - <[email protected]>
1819
abstract contract ForwarderModule is BaseModule
1920
{
21+
using AddressUtil for address;
2022
using BytesUtil for bytes;
2123
using MathUint for uint;
2224
using SignatureUtil for bytes32;

packages/hebao_v1/contracts/modules/transfers/BaseTransferModule.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ abstract contract BaseTransferModule is SecurityModule
3939
address token,
4040
address to,
4141
uint amount,
42-
bytes memory logdata
42+
bytes calldata logdata
4343
)
4444
internal
4545
{
@@ -80,7 +80,7 @@ abstract contract BaseTransferModule is SecurityModule
8080
address wallet,
8181
address to,
8282
uint value,
83-
bytes memory txData
83+
bytes calldata txData
8484
)
8585
internal
8686
virtual

packages/hebao_v1/contracts/thirdparty/ens/BaseENSManager.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ contract BaseENSManager is IENSManager, OwnerManagable, ENSConsumer {
162162
function verifyApproval(
163163
address _wallet,
164164
address _owner,
165-
string memory _label,
166-
bytes memory _approval
165+
string calldata _label,
166+
bytes calldata _approval
167167
)
168168
internal
169169
view

packages/hebao_v1/legacy/version1.0/contracts/transfers/QuotaTransfers.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ contract QuotaTransfers is TransferModule
152152
address wallet,
153153
address to,
154154
uint value,
155-
bytes memory txData
155+
bytes calldata txData
156156
)
157157
internal
158158
override

packages/hebao_v1/legacy/version1.0/contracts/transfers/TransferModule.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract contract TransferModule is SecurityModule
9393
address wallet,
9494
address to,
9595
uint value,
96-
bytes memory txData
96+
bytes calldata txData
9797
)
9898
internal
9999
virtual

packages/loopring_v3/contracts/lib/AddressUtil.sol

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,49 @@ library AddressUtil
6868
success = to.sendETH(amount, gasLimit);
6969
require(success, "TRANSFER_FAILURE");
7070
}
71+
72+
// Works like call but is slightly more efficient when data
73+
// needs to be copied from memory to do the call.
74+
function fastCall(
75+
address to,
76+
uint gasLimit,
77+
uint value,
78+
bytes memory data
79+
)
80+
internal
81+
returns (bool success, bytes memory returnData)
82+
{
83+
if (to != address(0)) {
84+
assembly {
85+
// Do the call
86+
success := call(gasLimit, to, value, add(data, 32), mload(data), 0, 0)
87+
// Copy the return data
88+
let size := returndatasize()
89+
returnData := mload(0x40)
90+
mstore(returnData, size)
91+
returndatacopy(add(returnData, 32), 0, size)
92+
// Update free memory pointer
93+
mstore(0x40, add(returnData, add(32, size)))
94+
}
95+
}
96+
}
97+
98+
// Like fastCall, but throws when the call is unsuccessful.
99+
function fastCallAndVerify(
100+
address to,
101+
uint gasLimit,
102+
uint value,
103+
bytes memory data
104+
)
105+
internal
106+
returns (bytes memory returnData)
107+
{
108+
bool success;
109+
(success, returnData) = fastCall(to, gasLimit, value, data);
110+
if (!success) {
111+
assembly {
112+
revert(add(returnData, 32), mload(returnData))
113+
}
114+
}
115+
}
71116
}

0 commit comments

Comments
 (0)