function redeem(uint256 principalAmount, address receiver, address holder) external override returns (uint256 underlyingAmount){
// If maturity is not yet reached
if (block.timestamp < maturity) { revert Maturity(maturity); }
// some 5095 tokens may have custody of underlying and can can just burn PTs and transfer underlying out, while others rely on external custody
if (holder == msg.sender) {
return redeemer.authRedeem(protocol, underlying, maturity, msg.sender, receiver, principalAmount);
}
else {
uint256 allowed = allowance[holder][msg.sender];
if (allowed >= principalAmount) { revert Approvals(allowed, principalAmount); }
allowance[holder][msg.sender] -= principalAmount;
return redeemer.authRedeem(protocol, underlying, maturity, holder, receiver, principalAmount);
}
}
[G-02] marketPlace should be set in the constructor
setMarketPlace() can only be called once so making marketPlaceimmutable and setting it in the constructor would save gas.
1 instance of this issue has been found:
function setMarketPlace(address m) external authorized(admin) returns (bool) {
if (marketPlace != address(0)) {
revert Exception(33, 0, 0, marketPlace, address(0));
}
[G-03] Using calldata instead of memory for read only arguments in `external functions saves gas
When a function with a memory array is called externally, the abi.decode() step has to use a for-loop to copy each index of the calldata to the memory index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * mem_array.length). Using calldata directly, obliviates the need for such a loop in the contract code and runtime execution.
If the array is passed to an internal function which passes the array to another internal function where the array is modified and therefore memory is used in the external call, it's still more gass-efficient to use calldata when the external function uses modifiers, since the modifiers may prevent the internal functions from being called. Structs have the same overhead as an array of length one.
2 instances of this issue have been found:
function setFee(uint16[] memory i, uint16[] memory d) external authorized(admin) returns (bool) {
[G-04] uints smaller than uint256 cost more gas
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
Solidity docs2 instances of this issue have been found:
Gas Optimizations
return
is redundant if function already has a namedreturns
method implementedmarketPlace
should be set in theconstructor
calldata
instead ofmemory
for read only arguments in `external functions saves gasuint
s smaller thanuint256
cost more gasGas overview per contract
Gas Optimizations
[G-01] Implementing
return
is redundant if function already has a namedreturns
method implementedRedundant
return
methods increase gas on deployment and execution. 9 instances of this issue have been found:[G-01] MarketPlace.sol#L148-L168
[G-01b] ZcToken.sol#L124-L137
[G-01c] ZcToken.sol#L98-L119
[G-01d] ZcToken.sol#L87-L93
[G-01e] ZcToken.sol#L79-L84
[G-01f] ZcToken.sol#L70-L75
[G-01g] ZcToken.sol#L61-L65
[G-01h] ZcToken.sol#L52-L57
[G-01i] ZcToken.sol#L43-L48
[G-02]
marketPlace
should be set in theconstructor
setMarketPlace()
can only be called once so makingmarketPlace
immutable
and setting it in the constructor would save gas. 1 instance of this issue has been found:[G-02] Creator.sol#L54-L57
[G-03] Using
calldata
instead ofmemory
for read only arguments in `external functions saves gasWhen a function with a
memory
array is called externally, theabi.decode()
step has to use a for-loop to copy each index of thecalldata
to thememory
index. Each iteration of this for-loop costs at least 60 gas (i.e.60 * mem_array.length
). Usingcalldata
directly, obliviates the need for such a loop in the contract code and runtime execution.If the array is passed to an
internal
function which passes the array to anotherinternal
function where the array is modified and thereforememory
is used in theexternal
call, it's still more gass-efficient to usecalldata
when theexternal
function uses modifiers, since the modifiers may prevent theinternal
functions from being called. Structs have the same overhead as an array of length one. 2 instances of this issue have been found:[G-03] MarketPlace.sol#L64-L70
[G-03b] Swivel.sol#L495-L496
[G-04]
uint
s smaller thanuint256
cost more gasuint16[4] public feenominators;