Skip to content

Commit 22aab9f

Browse files
authored
Merge pull request #604 from PolymathNetwork/gtm-matm-optimizations
Gtm matm optimizations
2 parents 4726245 + 68cdab9 commit 22aab9f

File tree

7 files changed

+174
-149
lines changed

7 files changed

+174
-149
lines changed

contracts/libraries/VersionUtils.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ library VersionUtils {
122122
* @notice Used to convert packed data into KYC data
123123
* @param _packedVersion Packed data
124124
*/
125-
function unpackKYC(uint256 _packedVersion) internal pure returns(uint64 fromTime, uint64 toTime, uint64 expiryTime, uint8 added) {
126-
fromTime = uint64(_packedVersion >> 136);
127-
toTime = uint64(_packedVersion >> 72);
125+
function unpackKYC(uint256 _packedVersion) internal pure returns(uint64 canSendAfter, uint64 canReceiveAfter, uint64 expiryTime, uint8 added) {
126+
canSendAfter = uint64(_packedVersion >> 136);
127+
canReceiveAfter = uint64(_packedVersion >> 72);
128128
expiryTime = uint64(_packedVersion >> 8);
129129
added = uint8(_packedVersion);
130130
}

contracts/modules/TransferManager/GTM/GeneralTransferManager.sol

Lines changed: 101 additions & 84 deletions
Large diffs are not rendered by default.

contracts/modules/TransferManager/GTM/GeneralTransferManagerStorage.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ contract GeneralTransferManagerStorage {
1515

1616
// Allows all TimeRestrictions to be offset
1717
struct Defaults {
18-
uint64 fromTime;
19-
uint64 toTime;
18+
uint64 canSendAfter;
19+
uint64 canReceiveAfter;
2020
}
2121

2222
// Offset to be applied to all timings (except KYC expiry)

contracts/modules/TransferManager/MATM/ManualApprovalTransferManager.sol

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
9292
view
9393
returns(Result, bytes32)
9494
{
95-
if (!paused && approvalIndex[_from][_to] != 0) {
96-
uint256 index = approvalIndex[_from][_to] - 1;
95+
uint256 index = approvalIndex[_from][_to];
96+
if (!paused && index != 0) {
97+
index--; //Actual index is storedIndex - 1
9798
ManualApproval memory approval = approvals[index];
9899
if ((approval.expiryTime >= now) && (approval.allowance >= _amount)) {
99100
return (Result.VALID, bytes32(uint256(address(this)) << 96));
@@ -166,95 +167,94 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
166167
* @param _from is the address from which transfers are approved
167168
* @param _to is the address to which transfers are approved
168169
* @param _expiryTime is the time until which the transfer is allowed
169-
* @param _changedAllowance is the changed allowance
170+
* @param _changeInAllowance is the change in allowance
170171
* @param _description Description about the manual approval
171-
* @param _change uint values which tells whether the allowances will be increased (1) or decreased (0)
172+
* @param _increase tells whether the allowances will be increased (true) or decreased (false).
172173
* or any value when there is no change in allowances
173174
*/
174175
function modifyManualApproval(
175176
address _from,
176177
address _to,
177178
uint256 _expiryTime,
178-
uint256 _changedAllowance,
179+
uint256 _changeInAllowance,
179180
bytes32 _description,
180-
uint8 _change
181+
bool _increase
181182
)
182183
external
183184
withPerm(ADMIN)
184185
{
185-
_modifyManualApproval(_from, _to, _expiryTime, _changedAllowance, _description, _change);
186+
_modifyManualApproval(_from, _to, _expiryTime, _changeInAllowance, _description, _increase);
186187
}
187188

188189
function _modifyManualApproval(
189190
address _from,
190191
address _to,
191192
uint256 _expiryTime,
192-
uint256 _changedAllowance,
193+
uint256 _changeInAllowance,
193194
bytes32 _description,
194-
uint8 _change
195+
bool _increase
195196
)
196197
internal
197198
{
198199
/*solium-disable-next-line security/no-block-members*/
199200
require(_expiryTime > now, "Invalid expiry time");
200-
require(approvalIndex[_from][_to] != 0, "Approval not present");
201-
uint256 index = approvalIndex[_from][_to] - 1;
201+
uint256 index = approvalIndex[_from][_to];
202+
require(index != 0, "Approval not present");
203+
index--; //Index is stored in an incremented form. 0 represnts non existant.
202204
ManualApproval storage approval = approvals[index];
203-
require(approval.allowance != 0 && approval.expiryTime > now, "Not allowed");
204-
uint256 currentAllowance = approval.allowance;
205-
uint256 newAllowance;
206-
if (_change == 1) {
207-
// Allowance get increased
208-
newAllowance = currentAllowance.add(_changedAllowance);
209-
approval.allowance = newAllowance;
210-
} else if (_change == 0) {
211-
// Allowance get decreased
212-
if (_changedAllowance > currentAllowance) {
213-
newAllowance = 0;
214-
approval.allowance = newAllowance;
205+
uint256 allowance = approval.allowance;
206+
uint256 expiryTime = approval.expiryTime;
207+
require(allowance != 0 && expiryTime > now, "Not allowed");
208+
209+
if (_changeInAllowance > 0) {
210+
if (_increase) {
211+
// Allowance get increased
212+
allowance = allowance.add(_changeInAllowance);
215213
} else {
216-
newAllowance = currentAllowance.sub(_changedAllowance);
217-
approval.allowance = newAllowance;
214+
// Allowance get decreased
215+
if (_changeInAllowance >= allowance) {
216+
allowance = 0;
217+
} else {
218+
allowance = allowance - _changeInAllowance;
219+
}
218220
}
219-
} else {
220-
// No change in the Allowance
221-
newAllowance = currentAllowance;
221+
approval.allowance = allowance;
222222
}
223223
// Greedy storage technique
224-
if (approval.expiryTime != _expiryTime) {
224+
if (expiryTime != _expiryTime) {
225225
approval.expiryTime = _expiryTime;
226226
}
227227
if (approval.description != _description) {
228228
approval.description = _description;
229229
}
230-
emit ModifyManualApproval(_from, _to, _expiryTime, newAllowance, _description, msg.sender);
230+
emit ModifyManualApproval(_from, _to, _expiryTime, allowance, _description, msg.sender);
231231
}
232232

233233
/**
234234
* @notice Adds mutiple manual approvals in batch
235235
* @param _from is the address array from which transfers are approved
236236
* @param _to is the address array to which transfers are approved
237237
* @param _expiryTimes is the array of the times until which eath transfer is allowed
238-
* @param _changedAllowances is the array of approved amounts
238+
* @param _changeInAllowance is the array of change in allowances
239239
* @param _descriptions is the description array for these manual approvals
240-
* @param _changes Array of uint values which tells whether the allowances will be increased (1) or decreased (0)
240+
* @param _increase Array of bools that tells whether the allowances will be increased (true) or decreased (false).
241241
* or any value when there is no change in allowances
242242
*/
243243
function modifyManualApprovalMulti(
244244
address[] memory _from,
245245
address[] memory _to,
246246
uint256[] memory _expiryTimes,
247-
uint256[] memory _changedAllowances,
247+
uint256[] memory _changeInAllowance,
248248
bytes32[] memory _descriptions,
249-
uint8[] memory _changes
249+
bool[] memory _increase
250250
)
251251
public
252252
withPerm(ADMIN)
253253
{
254-
_checkInputLengthArray(_from, _to, _changedAllowances, _expiryTimes, _descriptions);
255-
require(_changes.length == _changedAllowances.length, "Input length array mismatch");
254+
_checkInputLengthArray(_from, _to, _changeInAllowance, _expiryTimes, _descriptions);
255+
require(_increase.length == _changeInAllowance.length, "Input length array mismatch");
256256
for (uint256 i = 0; i < _from.length; i++) {
257-
_modifyManualApproval(_from[i], _to[i], _expiryTimes[i], _changedAllowances[i], _descriptions[i], _changes[i]);
257+
_modifyManualApproval(_from[i], _to[i], _expiryTimes[i], _changeInAllowance[i], _descriptions[i], _increase[i]);
258258
}
259259
}
260260

@@ -268,12 +268,14 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
268268
}
269269

270270
function _revokeManualApproval(address _from, address _to) internal {
271-
require(approvalIndex[_from][_to] != 0, "Approval not exist");
271+
uint256 index = approvalIndex[_from][_to];
272+
require(index != 0, "Approval not exist");
272273

273274
// find the record in active approvals array & delete it
274-
uint256 index = approvalIndex[_from][_to] - 1;
275-
if (index != approvals.length -1) {
276-
approvals[index] = approvals[approvals.length -1];
275+
index--; //Index is stored after incrementation so that 0 represents non existant index
276+
uint256 lastApprovalIndex = approvals.length - 1;
277+
if (index != lastApprovalIndex) {
278+
approvals[index] = approvals[lastApprovalIndex];
277279
approvalIndex[approvals[index].from][approvals[index].to] = index + 1;
278280
}
279281
delete approvalIndex[_from][_to];
@@ -323,7 +325,8 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
323325
*/
324326
function getActiveApprovalsToUser(address _user) external view returns(address[] memory, address[] memory, uint256[] memory, uint256[] memory, bytes32[] memory) {
325327
uint256 counter = 0;
326-
for (uint256 i = 0; i < approvals.length; i++) {
328+
uint256 approvalsLength = approvals.length;
329+
for (uint256 i = 0; i < approvalsLength; i++) {
327330
if ((approvals[i].from == _user || approvals[i].to == _user)
328331
&& approvals[i].expiryTime >= now)
329332
counter ++;
@@ -336,7 +339,7 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
336339
bytes32[] memory description = new bytes32[](counter);
337340

338341
counter = 0;
339-
for (uint256 i = 0; i < approvals.length; i++) {
342+
for (uint256 i = 0; i < approvalsLength; i++) {
340343
if ((approvals[i].from == _user || approvals[i].to == _user)
341344
&& approvals[i].expiryTime >= now) {
342345

@@ -360,8 +363,9 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
360363
* @return uint256 Description provided to the approval
361364
*/
362365
function getApprovalDetails(address _from, address _to) external view returns(uint256, uint256, bytes32) {
363-
if (approvalIndex[_from][_to] != 0) {
364-
uint256 index = approvalIndex[_from][_to] - 1;
366+
uint256 index = approvalIndex[_from][_to];
367+
if (index != 0) {
368+
index--;
365369
if (index < approvals.length) {
366370
ManualApproval storage approval = approvals[index];
367371
return(
@@ -390,13 +394,14 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage,
390394
* @return bytes32[] descriptions provided to the approvals
391395
*/
392396
function getAllApprovals() external view returns(address[] memory, address[] memory, uint256[] memory, uint256[] memory, bytes32[] memory) {
393-
address[] memory from = new address[](approvals.length);
394-
address[] memory to = new address[](approvals.length);
395-
uint256[] memory allowance = new uint256[](approvals.length);
396-
uint256[] memory expiryTime = new uint256[](approvals.length);
397-
bytes32[] memory description = new bytes32[](approvals.length);
398-
399-
for (uint256 i = 0; i < approvals.length; i++) {
397+
uint256 approvalsLength = approvals.length;
398+
address[] memory from = new address[](approvalsLength);
399+
address[] memory to = new address[](approvalsLength);
400+
uint256[] memory allowance = new uint256[](approvalsLength);
401+
uint256[] memory expiryTime = new uint256[](approvalsLength);
402+
bytes32[] memory description = new bytes32[](approvalsLength);
403+
404+
for (uint256 i = 0; i < approvalsLength; i++) {
400405

401406
from[i]=approvals[i].from;
402407
to[i]=approvals[i].to;

contracts/modules/TransferManager/MATM/ManualApprovalTransferManagerStorage.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ contract ManualApprovalTransferManagerStorage {
1515
}
1616

1717
mapping (address => mapping (address => uint256)) public approvalIndex;
18-
// An array to track all approvals
18+
19+
// An array to track all approvals. It is an unbounded array but it's not a problem as
20+
// it is never looped through in an onchain call. It is defined as an Array instead of mapping
21+
// just to make it easier for users to fetch list of all approvals through constant functions.
1922
ManualApproval[] public approvals;
2023

2124
}

test/h_general_transfer_manager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ contract("GeneralTransferManager", async (accounts) => {
859859
await increaseTime(10000);
860860

861861

862-
I_GeneralTransferManager.modifyKYCDataSignedMulti(
862+
await I_GeneralTransferManager.modifyKYCDataSignedMulti(
863863
[account_investor1, account_investor2],
864864
[fromTime, fromTime],
865865
[toTime, toTime],

test/j_manual_approval_transfer_manager.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ contract("ManualApprovalTransferManager", accounts => {
456456
currentTime.add(new BN(duration.days(2))),
457457
web3.utils.toWei("5"),
458458
web3.utils.fromAscii("New Description"),
459-
0,
459+
false,
460460
{
461461
from: token_owner
462462
}
@@ -492,9 +492,9 @@ contract("ManualApprovalTransferManager", accounts => {
492492
account_investor1,
493493
account_investor4,
494494
expiryTimeMA,
495-
web3.utils.toWei("5"),
495+
0,
496496
web3.utils.fromAscii("New Description"),
497-
45,
497+
true,
498498
{
499499
from: token_owner
500500
}
@@ -530,7 +530,7 @@ contract("ManualApprovalTransferManager", accounts => {
530530
expiryTimeMA,
531531
web3.utils.toWei("4"),
532532
web3.utils.fromAscii("New Description"),
533-
1,
533+
true,
534534
{
535535
from: token_owner
536536
}
@@ -560,7 +560,7 @@ contract("ManualApprovalTransferManager", accounts => {
560560
expiryTimeMA,
561561
web3.utils.toWei("1"),
562562
web3.utils.fromAscii("New Description"),
563-
0,
563+
false,
564564
{
565565
from: token_owner
566566
}
@@ -596,7 +596,7 @@ contract("ManualApprovalTransferManager", accounts => {
596596
expiryTimeMA,
597597
web3.utils.toWei("5"),
598598
web3.utils.fromAscii("New Description"),
599-
0,
599+
false,
600600
{
601601
from: token_owner
602602
}

0 commit comments

Comments
 (0)