Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

Commit

Permalink
Gas opti (#6)
Browse files Browse the repository at this point in the history
* removed deposit small and amount 0 check

* removed sender checks

* removed valid stream

* added update sender function

* cleanup
  • Loading branch information
sarangparikh22 committed Feb 1, 2022
1 parent f14fbef commit 57175f5
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 119 deletions.
48 changes: 13 additions & 35 deletions contracts/Furo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,12 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
error NotSenderOrRecipient();
error InvalidStream();
error InvalidAddressZero();
error InvalidAddressFuro();
error InvalidAddressSender();
error ZeroDeposit();
error InvalidStartTime();
error InvalidEndTime();
error InvalidDepositSmall();
error InvalidDepositMultipleOfTime();
error InvalidWithdrawTooMuch();
error InvalidSwapper();
error NotRecipient();
error NotSender();
error ReceivedTooLess();

modifier onlySenderOrRecipient(uint256 streamId) {
Expand All @@ -41,13 +37,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
_;
}

modifier validStream(uint256 streamId) {
if (!(streams[streamId].sender != address(0))) {
revert InvalidStream();
}
_;
}

constructor(IBentoBoxMinimal _bentoBox, address _wETH) {
bentoBox = _bentoBox;
wETH = _wETH;
Expand Down Expand Up @@ -83,20 +72,11 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
external
payable
override
returns (
uint256 streamId,
uint256 depositedShares
)
returns (uint256 streamId, uint256 depositedShares)
{
if (recipient == address(0)) revert InvalidAddressZero();
if (recipient == address(this)) revert InvalidAddressFuro();
if (recipient == msg.sender) revert InvalidAddressSender();
if (amount == 0) revert ZeroDeposit();
if (startTime < block.timestamp) revert InvalidStartTime();
if (endTime <= startTime) revert InvalidEndTime();

uint256 timeDifference = endTime - startTime;

depositedShares = _depositToken(
token,
msg.sender,
Expand All @@ -105,8 +85,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
fromBentoBox
);

if (depositedShares < timeDifference) revert InvalidDepositSmall();

streamId = streamIds++;

streams[streamId] = Stream({
Expand Down Expand Up @@ -139,7 +117,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
)
external
override
validStream(streamId)
onlySenderOrRecipient(streamId)
returns (uint256 recipientBalance, address to)
{
Expand Down Expand Up @@ -179,12 +156,7 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
ISwapReceiver swapReceiver,
bytes calldata data,
bool toBentoBox
)
external
override
validStream(streamId)
returns (uint256 recipientBalance)
{
) external override returns (uint256 recipientBalance) {
if (!whitelistedReceivers[swapReceiver]) revert InvalidSwapper();
Stream storage stream = streams[streamId];
if (msg.sender != stream.recipient) revert NotRecipient();
Expand Down Expand Up @@ -239,7 +211,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
function cancelStream(uint256 streamId, bool toBentoBox)
external
override
validStream(streamId)
onlySenderOrRecipient(streamId)
returns (uint256 senderBalance, uint256 recipientBalance)
{
Expand Down Expand Up @@ -276,7 +247,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
external
view
override
validStream(streamId)
returns (Stream memory)
{
return streams[streamId];
Expand All @@ -286,7 +256,6 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
external
view
override
validStream(streamId)
returns (uint256 senderBalance, uint256 recipientBalance)
{
return _balanceOf(streams[streamId]);
Expand All @@ -306,12 +275,21 @@ contract Furo is IFuro, BoringOwnable, BoringBatchable {
} else {
uint256 timeDelta = block.timestamp - stream.startTime;
recipientBalance =
(stream.depositedShares * timeDelta / (stream.endTime - stream.startTime)) -
((stream.depositedShares * timeDelta) /
(stream.endTime - stream.startTime)) -
uint256(stream.withdrawnShares);
senderBalance = uint256(stream.depositedShares) - recipientBalance;
}
}

function updateSender(uint256 streamId, address sender) external override {
Stream storage stream = streams[streamId];
if (sender == address(0)) revert InvalidAddressZero();
if (stream.sender == address(0)) revert InvalidStream();
if (msg.sender != stream.sender) revert NotSender();
stream.sender = sender;
}

function whitelistReceiver(ISwapReceiver receiver, bool approved)
external
onlyOwner
Expand Down
2 changes: 2 additions & 0 deletions contracts/interfaces/IFuro.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ interface IFuro {
external
returns (uint256 senderBalance, uint256 recipientBalance);

function updateSender(uint256 streamId, address sender) external;

function balanceOf(uint256 streamId)
external
view
Expand Down
131 changes: 47 additions & 84 deletions test/furo-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,105 +189,88 @@ describe("Stream Creation", function () {
expect(recipientBalance).to.be.eq(getBigNumber(0));
});

it("should not be able create stream when startTime is less than block.timestamp", async function () {
const startTime = await latest();
const endTime = startTime.add(BigNumber.from(3600));

it("should allow sender to be updated", async function () {
const amount = getBigNumber(10000);
const amountToShares = await toShare(bento, tokens[0], amount);
const amountToDeposit = await toAmount(bento, tokens[0], amountToShares);

const amountToDeposit = amountToShares;
const oldStreamId = await snapshotStreamId(furo);

await expect(
furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
true
)
).to.be.revertedWith(customError("InvalidStartTime"));
});
await furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
false
);

it("should not be able create stream when endTime is less than startTime", async function () {
await expect(
furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
startTime,
getBigNumber(1000),
true
)
).to.be.revertedWith(customError("InvalidEndTime"));
await furo.updateSender(oldStreamId, accounts[2].address);

const newStreamData = await snapshotStreamData(furo, oldStreamId);

expect(newStreamData.sender).to.be.eq(accounts[2].address);
});

it("should not stream to invalid recipients", async function () {
it("should not allow sender to be updated", async function () {
const amount = getBigNumber(10000);
const amountToShares = await toShare(bento, tokens[0], amount);

const amountToDeposit = await toAmount(bento, tokens[0], amountToShares);

await expect(
furo.createStream(
ADDRESS_ZERO,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
true
)
).to.be.revertedWith(customError("InvalidAddressZero"));
const oldStreamId = await snapshotStreamId(furo);

await expect(
furo.createStream(
furo.address,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
true
)
).to.be.revertedWith(customError("InvalidAddressFuro"));
await furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
false
);

await expect(
furo.createStream(
accounts[0].address,
tokens[0].address,
startTime,
endTime,
amountToDeposit,
true
)
).to.be.revertedWith(customError("InvalidAddressSender"));
furo.connect(accounts[1]).updateSender(oldStreamId, accounts[2].address)
).to.be.revertedWith(customError("NotSender"));
await expect(
furo.updateSender(oldStreamId, ADDRESS_ZERO)
).to.be.revertedWith(customError("InvalidAddressZero"));
await expect(
furo.updateSender(oldStreamId.add(1), accounts[2].address)
).to.be.revertedWith(customError("InvalidStream"));
});

it("should not stream when invalid deposit", async function () {
it("should not be able create stream when startTime is less than block.timestamp", async function () {
const startTime = await latest();
const endTime = startTime.add(BigNumber.from(3600));

const amount = getBigNumber(10000);
const amountToShares = await toShare(bento, tokens[0], amount);

const amountToDeposit = amountToShares;

await expect(
furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
endTime,
0,
amountToDeposit,
true
)
).to.be.revertedWith(customError("ZeroDeposit"));
).to.be.revertedWith(customError("InvalidStartTime"));
});

it("should not be able create stream when endTime is less than startTime", async function () {
await expect(
furo.createStream(
accounts[1].address,
tokens[0].address,
startTime,
endTime,
1,
startTime,
getBigNumber(1000),
true
)
).to.be.revertedWith(customError("InvalidDepositSmall"));
).to.be.revertedWith(customError("InvalidEndTime"));
});
});

Expand Down Expand Up @@ -661,12 +644,6 @@ describe("Stream Balances", function () {
expect(senderBalance).to.be.eq(0);
expect(recipientBalance).to.be.eq(amountToDeposit);
});

it("should not get balances from invalid stream id", async function () {
await expect(furo.balanceOf(streamId + 1)).to.be.revertedWith(
customError("InvalidStream")
);
});
});

describe("Stream Withdraw", function () {
Expand Down Expand Up @@ -1100,20 +1077,6 @@ describe("Stream Cancel", function () {
).to.be.revertedWith(customError("NotSenderOrRecipient"));
});

it("should allow sender to cancel the stream", async function () {
await furo.connect(accounts[0]).cancelStream(streamId, true);
await expect(snapshotStreamData(furo, streamId)).to.be.revertedWith(
customError("InvalidStream")
);
});

it("should allow recipient to cancel the stream", async function () {
await furo.connect(accounts[1]).cancelStream(streamId, true);
await expect(snapshotStreamData(furo, streamId)).to.be.revertedWith(
customError("InvalidStream")
);
});

it("should cancel stream after x time and distribute correct amounts - bento", async function () {
const streamData = await snapshotStreamData(furo, streamId);
const timeNow = await latest();
Expand Down

0 comments on commit 57175f5

Please sign in to comment.