Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test non-18-decimal tokens #78

Merged
merged 4 commits into from
Jun 26, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 0 additions & 55 deletions src/SablierV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ abstract contract SablierV2 is ISablierV2 {
/// @inheritdoc ISablierV2
uint256 public override nextStreamId;

/// INTERNAL STORAGE ///

/// @dev Mapping from owners to creators to stream creation authorizations.
mapping(address => mapping(address => mapping(IERC20 => uint256))) internal authorizations;

/// CONSTRUCTOR ///

constructor() {
Expand All @@ -27,15 +22,6 @@ abstract contract SablierV2 is ISablierV2 {

/// CONSTANT FUNCTIONS ///

/// @inheritdoc ISablierV2
function getAuthorization(
address sender,
address funder,
IERC20 token
) external view returns (uint256 authorization) {
authorization = authorizations[sender][funder][token];
}

/// @inheritdoc ISablierV2
function getRecipient(uint256 streamId) public view virtual override returns (address recipient);

Expand Down Expand Up @@ -82,28 +68,6 @@ abstract contract SablierV2 is ISablierV2 {
}
}

/// @inheritdoc ISablierV2
function decreaseAuthorization(
address funder,
IERC20 token,
uint256 amount
) public virtual override {
address sender = msg.sender;
uint256 newAuthorization = authorizations[sender][funder][token] - amount;
authorizeInternal(sender, funder, token, newAuthorization);
}

/// @inheritdoc ISablierV2
function increaseAuthorization(
address funder,
IERC20 token,
uint256 amount
) public virtual override {
address sender = msg.sender;
uint256 newAuthorization = authorizations[sender][funder][token] + amount;
authorizeInternal(sender, funder, token, newAuthorization);
}

/// INTERNAL CONSTANT FUNCTIONS ///

/// @dev Checks the basic requiremenets for the `create` function.
Expand Down Expand Up @@ -143,25 +107,6 @@ abstract contract SablierV2 is ISablierV2 {

/// INTERNAL NON-CONSTANT FUNCTIONS ///

/// @dev See the documentation for the public functions that call this internal function.
function authorizeInternal(
address sender,
address funder,
IERC20 token,
uint256 amount
) internal virtual {
// Checks: the would-be stream sender is not the zero address.
if (sender == address(0)) {
revert SablierV2__AuthorizeSenderZeroAddress();
}

// Effects: update the authorization for the given sender and funder pair.
authorizations[sender][funder][token] = amount;

// Emit an event.
emit Authorize(sender, funder, amount);
}

/// @dev See the documentation for the public functions that call this internal function.
function cancelInternal(uint256 streamId) internal virtual;
}
28 changes: 0 additions & 28 deletions src/SablierV2Cliff.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,6 @@ contract SablierV2Cliff is
revert SablierV2__FunderZeroAddress();
}

// If the `funder` is not the `msg.sender`, we have to perform some authorization checks.
if (funder != msg.sender) {
// Checks: the caller has sufficient authorization to create this stream on behalf of `funder`.
uint256 authorization = authorizations[funder][msg.sender][token];
if (authorization < depositAmount) {
revert SablierV2__InsufficientAuthorization(funder, msg.sender, token, authorization, depositAmount);
}

// Effects: decrease the authorization since this stream consumes a part or all of it.
unchecked {
authorizeInternal(funder, msg.sender, token, authorization - depositAmount);
}
}

// Checks, Effects and Interactions: create the stream.
streamId = createInternal(
funder,
Expand Down Expand Up @@ -204,20 +190,6 @@ contract SablierV2Cliff is
revert SablierV2__FunderZeroAddress();
}

// If the `funder` is not the `msg.sender`, we have to perform some authorization checks.
if (funder != msg.sender) {
// Checks: `msg.sender` has sufficient authorization to create this stream on behalf of `funder`.
uint256 authorization = authorizations[funder][msg.sender][token];
if (authorization < depositAmount) {
revert SablierV2__InsufficientAuthorization(funder, msg.sender, token, authorization, depositAmount);
}

// Effects: decrease the authorization since this stream consumes a part or all of it.
unchecked {
authorizeInternal(funder, msg.sender, token, authorization - depositAmount);
}
}

// Calculate the cliff time and the stop time. It is fine to use unchecked arithmetic because the
// `createInternal` function will nonetheless check that the stop time is greater than or equal to the
// cliff time, and that the cliff time is greater than or equal to the start time.
Expand Down
28 changes: 0 additions & 28 deletions src/SablierV2Linear.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,6 @@ contract SablierV2Linear is
uint256 stopTime,
bool cancelable
) external returns (uint256 streamId) {
// If the `funder` is not the `msg.sender`, we have to perform some authorization checks.
if (funder != msg.sender) {
// Checks: the caller has sufficient authorization to create this stream on behalf of `funder`.
uint256 authorization = authorizations[funder][msg.sender][token];
if (authorization < depositAmount) {
revert SablierV2__InsufficientAuthorization(funder, msg.sender, token, authorization, depositAmount);
}

// Effects: decrease the authorization since this stream consumes a part of all of it.
unchecked {
authorizeInternal(funder, msg.sender, token, authorization - depositAmount);
}
}

// Checks, Effects and Interactions: create the stream.
streamId = createInternal(funder, sender, recipient, depositAmount, token, startTime, stopTime, cancelable);
}
Expand All @@ -177,20 +163,6 @@ contract SablierV2Linear is
uint256 duration,
bool cancelable
) external returns (uint256 streamId) {
// If the `funder` is not the `msg.sender`, we have to perform some authorization checks.
if (funder != msg.sender) {
// Checks: `msg.sender` has sufficient authorization to create this stream on behalf of `funder`.
uint256 authorization = authorizations[funder][msg.sender][token];
if (authorization < depositAmount) {
revert SablierV2__InsufficientAuthorization(funder, msg.sender, token, authorization, depositAmount);
}

// Effects: decrease the authorization since this stream consumes a part or all of it.
unchecked {
authorizeInternal(funder, msg.sender, token, authorization - depositAmount);
}
}

// Calculate the stop time. It is fine to use unchecked arithmetic because the `createInternal` function will
// nonetheless check that the stop time is greater than or equal to the start time.
uint256 startTime = block.timestamp;
Expand Down
14 changes: 0 additions & 14 deletions src/SablierV2Pro.sol
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,6 @@ contract SablierV2Pro is
revert SablierV2__FunderZeroAddress();
}

// If the `funder` is not the `msg.sender`, we have to perform some authorization checks.
if (funder != msg.sender) {
// Checks: the caller has sufficient authorization to create this stream on behalf of `funder`.
uint256 authorization = authorizations[funder][msg.sender][token];
if (authorization < depositAmount) {
revert SablierV2__InsufficientAuthorization(funder, msg.sender, token, authorization, depositAmount);
}

// Effects: decrease the authorization since this stream consumes a part of all of it.
unchecked {
authorizeInternal(funder, msg.sender, token, authorization - depositAmount);
}
}

// Checks, Effects and Interactions: create the stream.
streamId = createInternal(
funder,
Expand Down
63 changes: 0 additions & 63 deletions src/interfaces/ISablierV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@ interface ISablierV2 {
/// @notice Emitted when attempting to create a stream on behalf of the zero address.
error SablierV2__FunderZeroAddress();

/// @notice Emitted when the funder does not have sufficient authorization to create a stream.
error SablierV2__InsufficientAuthorization(
address sender,
address funder,
IERC20 token,
uint256 authorization,
uint256 depositAmount
);

/// @notice Emitted when attempting to create a stream with recipient as the zero address.
error SablierV2__RecipientZeroAddress();

Expand Down Expand Up @@ -70,12 +61,6 @@ interface ISablierV2 {

/// EVENTS ///

/// @notice Emitted when an authorization to create streams is granted.
/// @param sender The address of the would-be stream sender.
/// @param funder The address of the stream funder.
/// @param amount The authorization that can be used for creating streams, as an 18-decimal number.
event Authorize(address indexed sender, address indexed funder, uint256 amount);

/// @notice Emitted when a stream is canceled.
/// @param streamId The id of the stream.
/// @param recipient The address of the recipient.
Expand All @@ -95,18 +80,6 @@ interface ISablierV2 {

/// CONSTANT FUNCTIONS ///

/// @notice Returns the authorization that `sender` has given `funder` to create streams.
/// @param sender The address of the would-be stream sender.
/// @param funder The address of the funder.
/// @param token The ERC-20 token for which to grant the authorization.
/// @return authorization The maximum amount that can be used for creating streams, in units of the token's
/// decimals.
function getAuthorization(
address sender,
address funder,
IERC20 token
) external view returns (uint256 authorization);

/// @notice Reads the amount deposited in the stream.
/// @param streamId The id of the stream to make the query for.
/// @return depositAmount The amount deposited in the stream, in units of the ERC-20 token's decimals.
Expand Down Expand Up @@ -180,42 +153,6 @@ interface ISablierV2 {
/// @param streamIds The ids of the streams to cancel.
function cancelAll(uint256[] calldata streamIds) external;

/// @notice Decreases the authorization given by `msg.sender` to `funder` to create streams using their
/// `token` balance.
///
/// @dev Emits an {Authorize} event indicating the updated authorization.
///
/// Requirements:
/// - `funder` must not be the zero address.
/// - `funder` must have an authorization from `msg.sender` of at least `amount`.
///
/// @param funder The address of the stream funder.
/// @param token The ERC-20 token for which to decrease the authorization.
/// @param amount The authorization to decrease, as an 18-decimal number.
function decreaseAuthorization(
address funder,
IERC20 token,
uint256 amount
) external;

/// @notice Increases the authorization given by `msg.sender` to `funder` to create streams using their
/// `token` balance.
///
/// @dev Emits an {Authorize} event indicating the updated authorization.
///
/// Requirements:
/// - `funder` must not be the zero address.
/// - The authorization calculations must not overflow uint256.
///
/// @param funder The address of the stream funder.
/// @param token The ERC-20 token for which to increase the authorization.
/// @param amount The amount by which to increase the authorization, in units of the token's decimals.
function increaseAuthorization(
address funder,
IERC20 token,
uint256 amount
) external;

/// @notice Counter for stream ids.
/// @return The next stream id.
function nextStreamId() external view returns (uint256);
Expand Down
14 changes: 9 additions & 5 deletions test/unit/SablierV2UnitTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ abstract contract SablierV2UnitTest is Test {
uint256 internal constant TOTAL_DURATION = 10_000 seconds;

uint256 internal immutable CLIFF_TIME;
uint256 internal immutable DEPOSIT_AMOUNT;
uint256 internal immutable DEPOSIT_AMOUNT_DAI;
uint256 internal immutable DEPOSIT_AMOUNT_USDC;
uint256 internal immutable START_TIME;
uint256 internal immutable STOP_TIME;

Expand All @@ -49,7 +50,8 @@ abstract contract SablierV2UnitTest is Test {

bytes32 internal nextUser = keccak256(abi.encodePacked("user address"));
NonStandardERC20 internal nonStandardToken = new NonStandardERC20("Stablecoin", "USD", 18);
GodModeERC20 internal usd = new GodModeERC20("Stablecoin", "USD", 18);
GodModeERC20 internal dai = new GodModeERC20("Dai Stablecoin", "DAI", 18);
GodModeERC20 internal usdc = new GodModeERC20("USD Coin", "USDC", 6);
Users internal users;

/// CONSTRUCTOR ///
Expand All @@ -61,7 +63,8 @@ abstract contract SablierV2UnitTest is Test {

// Initialize the default stream values.
CLIFF_TIME = block.timestamp + CLIFF_DURATION;
DEPOSIT_AMOUNT = bn(10_000);
DEPOSIT_AMOUNT_DAI = bn(10_000, 18);
DEPOSIT_AMOUNT_USDC = bn(10_000, 6);
START_TIME = block.timestamp;
STOP_TIME = block.timestamp + TOTAL_DURATION;

Expand Down Expand Up @@ -179,8 +182,9 @@ abstract contract SablierV2UnitTest is Test {
/// @dev Give user 100 ETH and 1M USD.
function fundUser(address payable user) internal {
vm.deal(user, 100 ether);
usd.mint(user, bn(1_000_000));
nonStandardToken.mint(user, bn(1_000_000));
dai.mint(user, bn(1_000_000, 18));
usdc.mint(user, bn(1_000_000, 6));
nonStandardToken.mint(user, bn(1_000_000, 18));
}
PaulRBerg marked this conversation as resolved.
Show resolved Hide resolved

/// @dev Converts bytes32 to address.
Expand Down

This file was deleted.

This file was deleted.

Loading