Skip to content

Commit

Permalink
Merge pull request #102 from sablier-labs/fix/hardcode-permit2
Browse files Browse the repository at this point in the history
fix: hardcode permit2 as immutable in proxy target
  • Loading branch information
PaulRBerg authored Jun 28, 2023
2 parents 5513789 + 2562121 commit f9cdfd0
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 26 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/deploy-periphery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ on:
default: "goerli"
description: "Chain name as defined in the Foundry config."
required: false
permit2:
default: "0x000000000022D473030F116dDEE9F6B43aC78BA3"
description: "The permit2 address."
required: false


jobs:
deploy-periphery:
Expand All @@ -43,10 +48,11 @@ jobs:
forge script script/DeployPeriphery.s.sol
--broadcast
--rpc-url "${{ inputs.chain }}"
--sig "run(address)"
--sig "run(address,address)"
--verify
-vvvv
"${{ inputs.admin }}"
"${{ inputs.permit2 }}"
- name: "Add workflow summary"
run: |
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/deploy-protocol.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ on:
default: "300"
description: "Maximum number of segments allowed in a stream."
required: false
permit2:
default: "0x000000000022D473030F116dDEE9F6B43aC78BA3"
description: "The permit2 address."
required: false

jobs:
deploy-protocol:
Expand All @@ -48,11 +52,12 @@ jobs:
forge script script/DeployProtocol.s.sol
--broadcast
--rpc-url "${{ inputs.chain }}"
--sig "run(address,uint256)"
--sig "run(address,uint256,address)"
--verify
-vvvv
"${{ inputs.admin }}"
"${{ inputs.max-segment-count }}"
-vvvv
"${{ inputs.permit2 }}"
- name: "Add workflow summary"
run: |
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/deploy-proxy-target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
default: "goerli"
description: "Chain name as defined in the Foundry config."
required: false
permit2:
default: "0x000000000022D473030F116dDEE9F6B43aC78BA3"
description: "The permit2 address."
required: false

jobs:
deploy-proxy-target:
Expand All @@ -39,8 +43,10 @@ jobs:
forge script script/DeployProxyTarget.s.sol
--broadcast
--rpc-url "${{ inputs.chain }}"
--sig "run(address)"
--verify
-vvvv
"${{ inputs.permit2 }}"
- name: "Add workflow summary"
run: |
Expand Down
6 changes: 4 additions & 2 deletions script/DeployDeterministicPeriphery.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity >=0.8.19 <=0.9.0;

import { BaseScript } from "@sablier/v2-core-script/Base.s.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { SablierV2Archive } from "../src/SablierV2Archive.sol";
import { SablierV2ProxyPlugin } from "../src/SablierV2ProxyPlugin.sol";
Expand All @@ -19,7 +20,8 @@ contract DeployDeterministicPeriphery is BaseScript {
/// https://github.com/Arachnid/deterministic-deployment-proxy
function run(
uint256 create2Salt,
address initialAdmin
address initialAdmin,
IAllowanceTransfer permit2
)
public
virtual
Expand All @@ -28,6 +30,6 @@ contract DeployDeterministicPeriphery is BaseScript {
{
archive = new SablierV2Archive{ salt: bytes32(create2Salt) }(initialAdmin);
plugin = new SablierV2ProxyPlugin{ salt: bytes32(create2Salt) }(archive);
target = new SablierV2ProxyTarget{ salt: bytes32(create2Salt) }();
target = new SablierV2ProxyTarget{ salt: bytes32(create2Salt) }(permit2);
}
}
13 changes: 11 additions & 2 deletions script/DeployDeterministicProxyTarget.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity >=0.8.19 <=0.9.0;

import { BaseScript } from "@sablier/v2-core-script/Base.s.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { SablierV2ProxyTarget } from "../src/SablierV2ProxyTarget.sol";

Expand All @@ -10,7 +11,15 @@ import { SablierV2ProxyTarget } from "../src/SablierV2ProxyTarget.sol";
contract DeployDeterministicProxyTarget is BaseScript {
/// @dev The presence of the salt instructs Forge to deploy contracts via this deterministic CREATE2 factory:
/// https://github.com/Arachnid/deterministic-deployment-proxy
function run(uint256 create2Salt) public virtual broadcaster returns (SablierV2ProxyTarget target) {
target = new SablierV2ProxyTarget{ salt: bytes32(create2Salt) }();
function run(
uint256 create2Salt,
IAllowanceTransfer permit2
)
public
virtual
broadcaster
returns (SablierV2ProxyTarget target)
{
target = new SablierV2ProxyTarget{ salt: bytes32(create2Salt) }(permit2);
}
}
8 changes: 6 additions & 2 deletions script/DeployPeriphery.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity >=0.8.19 <0.9.0;

import { BaseScript } from "@sablier/v2-core-script/Base.s.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { SablierV2Archive } from "../src/SablierV2Archive.sol";
import { SablierV2ProxyPlugin } from "../src/SablierV2ProxyPlugin.sol";
Expand All @@ -13,13 +14,16 @@ import { SablierV2ProxyTarget } from "../src/SablierV2ProxyTarget.sol";
/// 2. {SablierV2ProxyPlugin}
/// 3. {SablierV2ProxyTarget}
contract DeployPeriphery is BaseScript {
function run(address initialAdmin)
function run(
address initialAdmin,
IAllowanceTransfer permit2
)
public
broadcaster
returns (SablierV2Archive archive, SablierV2ProxyPlugin plugin, SablierV2ProxyTarget target)
{
archive = new SablierV2Archive(initialAdmin);
plugin = new SablierV2ProxyPlugin(archive);
target = new SablierV2ProxyTarget();
target = new SablierV2ProxyTarget(permit2);
}
}
6 changes: 4 additions & 2 deletions script/DeployProtocol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SablierV2LockupDynamic } from "@sablier/v2-core/SablierV2LockupDynamic.
import { SablierV2LockupLinear } from "@sablier/v2-core/SablierV2LockupLinear.sol";
import { SablierV2NFTDescriptor } from "@sablier/v2-core/SablierV2NFTDescriptor.sol";
import { BaseScript } from "@sablier/v2-core-script/Base.s.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { SablierV2Archive } from "../src/SablierV2Archive.sol";
import { SablierV2ProxyPlugin } from "../src/SablierV2ProxyPlugin.sol";
Expand All @@ -15,7 +16,8 @@ import { SablierV2ProxyTarget } from "../src/SablierV2ProxyTarget.sol";
contract DeployProtocol is BaseScript {
function run(
address initialAdmin,
uint256 maxSegmentCount
uint256 maxSegmentCount,
IAllowanceTransfer permit2
)
public
virtual
Expand All @@ -39,7 +41,7 @@ contract DeployProtocol is BaseScript {
// Deploy V2 Periphery.
archive = new SablierV2Archive(initialAdmin);
plugin = new SablierV2ProxyPlugin(archive);
target = new SablierV2ProxyTarget();
target = new SablierV2ProxyTarget(permit2);

// List the streaming contracts.
archive.list(address(lockupDynamic));
Expand Down
5 changes: 3 additions & 2 deletions script/DeployProxyTarget.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
pragma solidity >=0.8.19 <0.9.0;

import { BaseScript } from "@sablier/v2-core-script/Base.s.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { SablierV2ProxyTarget } from "../src/SablierV2ProxyTarget.sol";

contract DeployProxyTarget is BaseScript {
function run() public broadcaster returns (SablierV2ProxyTarget target) {
target = new SablierV2ProxyTarget();
function run(IAllowanceTransfer permit2) public broadcaster returns (SablierV2ProxyTarget target) {
target = new SablierV2ProxyTarget(permit2);
}
}
23 changes: 17 additions & 6 deletions src/SablierV2ProxyTarget.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ISablierV2Lockup } from "@sablier/v2-core/interfaces/ISablierV2Lockup.s
import { ISablierV2LockupLinear } from "@sablier/v2-core/interfaces/ISablierV2LockupLinear.sol";
import { ISablierV2LockupDynamic } from "@sablier/v2-core/interfaces/ISablierV2LockupDynamic.sol";
import { LockupDynamic, LockupLinear } from "@sablier/v2-core/types/DataTypes.sol";
import { IAllowanceTransfer } from "permit2/interfaces/IAllowanceTransfer.sol";

import { OnlyDelegateCall } from "./abstracts/OnlyDelegateCall.sol";
import { ISablierV2ProxyTarget } from "./interfaces/ISablierV2ProxyTarget.sol";
Expand Down Expand Up @@ -42,6 +43,20 @@ contract SablierV2ProxyTarget is
{
using SafeERC20 for IERC20;

/*//////////////////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////////////////*/

IAllowanceTransfer internal immutable PERMIT2;

/*//////////////////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////////////////*/

constructor(IAllowanceTransfer permit2) {
PERMIT2 = permit2;
}

/*//////////////////////////////////////////////////////////////////////////
SABLIER-V2-LOCKUP
//////////////////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -676,14 +691,10 @@ contract SablierV2ProxyTarget is
address owner_ = owner;

// Permit the proxy to spend funds from the proxy owner.
permit2Params.permit2.permit({
owner: owner_,
permitSingle: permit2Params.permitSingle,
signature: permit2Params.signature
});
PERMIT2.permit({ owner: owner_, permitSingle: permit2Params.permitSingle, signature: permit2Params.signature });

// Transfer funds from the proxy owner to the proxy.
permit2Params.permit2.transferFrom({ from: owner_, to: address(this), amount: amount, token: address(asset) });
PERMIT2.transferFrom({ from: owner_, to: address(this), amount: amount, token: address(asset) });

// Approve the Sablier contract to spend funds.
_approve(sablierContract, asset, amount);
Expand Down
2 changes: 0 additions & 2 deletions src/types/DataTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ library Batch {

/// @notice A struct encapsulating the parameters needed for Permit2.
/// @dev See the full documentation at https://github.com/Uniswap/permit2.
/// @param permit2 The address of the Permit2 contract.
/// @param permitSingle The permit message signed for a single token allowance.
/// @param signature The ECDSA signature of the permit, which contains the three parameters (r,s,v).
struct Permit2Params {
IAllowanceTransfer permit2;
IAllowanceTransfer.PermitSingle permitSingle;
bytes signature;
}
10 changes: 6 additions & 4 deletions test/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ abstract contract Base_Test is Assertions, Events, StdCheats, V2CoreUtils {
if (!isTestOptimizedProfile()) {
archive = new SablierV2Archive(users.admin.addr);
plugin = new SablierV2ProxyPlugin(archive);
target = new SablierV2ProxyTarget();
target = new SablierV2ProxyTarget(permit2);
} else {
archive = deployPrecompiledArchive(users.admin.addr);
plugin = deployPrecompiledPlugin(archive);
target = deployPrecompiledTarget();
target = deployPrecompiledTarget(permit2);
}
}

Expand All @@ -108,8 +108,10 @@ abstract contract Base_Test is Assertions, Events, StdCheats, V2CoreUtils {
}

/// @dev Deploys {SablierV2ProxyTarget} from a source precompiled with `--via-ir`.
function deployPrecompiledTarget() internal returns (ISablierV2ProxyTarget) {
return ISablierV2ProxyTarget(deployCode("out-optimized/SablierV2ProxyTarget.sol/SablierV2ProxyTarget.json"));
function deployPrecompiledTarget(IAllowanceTransfer permit2_) internal returns (ISablierV2ProxyTarget) {
return ISablierV2ProxyTarget(
deployCode("out-optimized/SablierV2ProxyTarget.sol/SablierV2ProxyTarget.json", abi.encode(permit2_))
);
}

/// @dev Labels the most relevant contracts.
Expand Down
1 change: 0 additions & 1 deletion test/utils/Defaults.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ contract Defaults is PermitSignature {
spender: spender
});
permit2Params_ = Permit2Params({
permit2: permit2,
permitSingle: permitSingle,
signature: getPermitSignature({
permit: permitSingle,
Expand Down

0 comments on commit f9cdfd0

Please sign in to comment.