instead of having:
mapping (address => uint256) private ubiBalance;
(...)
mapping(address => uint256) public accruedSince;
you can do this:
struct UbiAccount {
uint224 balance;
uint32 timestamp;
}
mapping(address => uint256) public ubiAccounts;
and update everything to support this new structure (cast uint256s to uint224s, etc)
Rationale
Every time you transfer, you need to write to both slots. Assuming best case (non-zero to non-zero), the updateBalance(...) that is called will incur:
(2900 + 2100) * 2 = 10_000
if you however have both the balance and accruedSince in the same slot, you rewrite on dirty and hot:
(2900 + 2100) + (100 + 100) = 5_200
all in all, this amounts to 4_800 gas saved.
instead of having:
you can do this:
and update everything to support this new structure (cast uint256s to uint224s, etc)
Rationale
Every time you transfer, you need to write to both slots. Assuming best case (non-zero to non-zero), the
updateBalance(...)that is called will incur:(2900 + 2100) * 2 = 10_000if you however have both the balance and accruedSince in the same slot, you rewrite on dirty and hot:
(2900 + 2100) + (100 + 100) = 5_200all in all, this amounts to 4_800 gas saved.