diff --git a/.gas-snapshot b/.gas-snapshot index 447dad07..60343027 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,156 +1,33 @@ -BatchCancelMultiple_TargetApprove_Integration_Test:test_BatchCancelMultiple() (gas: 4279984) -BatchCancelMultiple_TargetPermit2_Integration_Test:test_BatchCancelMultiple() (gas: 4365085) -BatchCancelMultiple_TargetPush_Integration_Test:test_BatchCancelMultiple() (gas: 4264839) -BatchCreateWithDeltas_TargetApprove_Integration_Test:test_BatchCreateWithDeltas() (gas: 2165768) -BatchCreateWithDeltas_TargetPermit2_Integration_Test:test_BatchCreateWithDeltas() (gas: 2223240) -BatchCreateWithDeltas_TargetPush_Integration_Test:test_BatchCreateWithDeltas() (gas: 2155334) -BatchCreateWithDurations_TargetApprove_Integration_Test:test_BatchCreateWithDurations() (gas: 1398065) -BatchCreateWithDurations_TargetPermit2_Integration_Test:test_BatchCreateWithDurations() (gas: 1455767) -BatchCreateWithDurations_TargetPush_Integration_Test:test_BatchCreateWithDurations() (gas: 1387974) -BatchCreateWithMilestones_TargetApprove_Integration_Test:test_BatchCreateWithMilestones() (gas: 2163757) -BatchCreateWithMilestones_TargetPermit2_Integration_Test:test_BatchCreateWithMilestones() (gas: 2221573) -BatchCreateWithMilestones_TargetPush_Integration_Test:test_BatchCreateWithMilestones() (gas: 2153632) -BatchCreateWithRange_TargetApprove_Integration_Test:test_BatchCreateWithRange() (gas: 1404653) -BatchCreateWithRange_TargetPermit2_Integration_Test:test_BatchCreateWithRange() (gas: 1462292) -BatchCreateWithRange_TargetPush_Integration_Test:test_BatchCreateWithRange() (gas: 1394491) -Burn_TargetApprove_Integration_Test:test_Burn_LockupDynamic() (gas: 335300) -Burn_TargetApprove_Integration_Test:test_Burn_LockupLinear() (gas: 273344) -Burn_TargetPermit2_Integration_Test:test_Burn_LockupDynamic() (gas: 382480) -Burn_TargetPermit2_Integration_Test:test_Burn_LockupLinear() (gas: 319415) -Burn_TargetPush_Integration_Test:test_Burn_LockupDynamic() (gas: 296206) -Burn_TargetPush_Integration_Test:test_Burn_LockupLinear() (gas: 234276) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithDeltas_AcrossSablierContracts() (gas: 577216) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithDeltas_SameSablierContract() (gas: 615744) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithDurations_AcrossSablierContracts() (gas: 575048) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithDurations_SameSablierContract() (gas: 459612) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithMilestones_AcrossSablierContracts() (gas: 576806) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithMilestones_SameSablierContract() (gas: 615268) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithRange_AcrossSablierContracts() (gas: 576141) -CancelAndCreate_TargetApprove_Integration_Test:test_CancelAndCreateWithRange_SameSablierContract() (gas: 460847) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithDeltas_AcrossSablierContracts() (gas: 662069) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithDeltas_SameSablierContract() (gas: 700607) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithDurations_AcrossSablierContracts() (gas: 659866) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithDurations_SameSablierContract() (gas: 542409) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithMilestones_AcrossSablierContracts() (gas: 661668) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithMilestones_SameSablierContract() (gas: 700119) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithRange_AcrossSablierContracts() (gas: 660960) -CancelAndCreate_TargetPermit2_Integration_Test:test_CancelAndCreateWithRange_SameSablierContract() (gas: 543954) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithDeltas_AcrossSablierContracts() (gas: 563919) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithDeltas_SameSablierContract() (gas: 602435) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithDurations_AcrossSablierContracts() (gas: 561728) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithDurations_SameSablierContract() (gas: 444293) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithMilestones_AcrossSablierContracts() (gas: 563514) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithMilestones_SameSablierContract() (gas: 601942) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithRange_AcrossSablierContracts() (gas: 562820) -CancelAndCreate_TargetPush_Integration_Test:test_CancelAndCreateWithRange_SameSablierContract() (gas: 445836) -CancelMultiple_TargetApprove_Integration_Test:test_CancelMultiple_LockupDynamic() (gas: 2580879) -CancelMultiple_TargetApprove_Integration_Test:test_CancelMultiple_LockupLinear() (gas: 1772627) -CancelMultiple_TargetPermit2_Integration_Test:test_CancelMultiple_LockupDynamic() (gas: 2638711) -CancelMultiple_TargetPermit2_Integration_Test:test_CancelMultiple_LockupLinear() (gas: 1830264) -CancelMultiple_TargetPush_Integration_Test:test_CancelMultiple_LockupDynamic() (gas: 2575666) -CancelMultiple_TargetPush_Integration_Test:test_CancelMultiple_LockupLinear() (gas: 1767359) -Cancel_TargetApprove_Integration_Test:test_Cancel_LockupDynamic() (gas: 391578) -Cancel_TargetApprove_Integration_Test:test_Cancel_LockupLinear() (gas: 310624) -Cancel_TargetPermit2_Integration_Test:test_Cancel_LockupDynamic() (gas: 449197) -Cancel_TargetPermit2_Integration_Test:test_Cancel_LockupLinear() (gas: 368239) -Cancel_TargetPush_Integration_Test:test_Cancel_LockupDynamic() (gas: 385420) -Cancel_TargetPush_Integration_Test:test_Cancel_LockupLinear() (gas: 304482) -Claim_Integration_Test:test_Claim() (gas: 276787) -Claim_Integration_Test:test_RevertGiven_AlreadyClaimed() (gas: 264794) -Clawback_Integration_Test:testFuzz_Clawback(address) (runs: 20, μ: 289894, ~: 289894) -Constructor_MerkleStreamerLL_Integration_Test:test_Constructor() (gas: 1057889) -CreateMerkleStreamerLL_Integration_Test:testFuzz_CreateMerkleStreamerLL(address,uint40) (runs: 20, μ: 1026355, ~: 1026355) -CreateMerkleStreamerLL_Integration_Test:test_RevertGiven_AlreadyDeployed() (gas: 8937393460516730614) -CreateWithDeltas_Integration_Test:test_BatchCreateWithDeltas() (gas: 2074463) -CreateWithDurations_Integration_Test:test_BatchCreateWithDurations() (gas: 1338378) -CreateWithMilestones_Integration_Test:test_BatchCreateWithMilestones() (gas: 2067917) -CreateWithRange_Integration_Test:test_CreateWithRange() (gas: 1340546) -GetMerkleStreamers_Integration_Test:test_GetMerkleStreamers() (gas: 964471) -GetMerkleStreamers_Integration_Test:test_GetMerkleStreamers_AdminDoesNotHaveMerkleStreamers(address) (runs: 20, μ: 13532, ~: 13532) -HasClaimed_Integration_Test:test_HasClaimed() (gas: 249939) -HasClaimed_Integration_Test:test_HasClaimed_IndexNotInTree() (gas: 7989) -HasClaimed_Integration_Test:test_HasClaimed_NotClaimed() (gas: 13246) -HasExpired_Integration_Test:test_HasExpired_ExpirationEqualToCurrentTime() (gas: 13949) -HasExpired_Integration_Test:test_HasExpired_ExpirationGreaterThanCurrentTime() (gas: 14043) -HasExpired_Integration_Test:test_HasExpired_ExpirationLessThanCurrentTime() (gas: 5738) -HasExpired_Integration_Test:test_HasExpired_ExpirationZero() (gas: 956412) +Claim_Integration_Test:test_Claim() (gas: 279147) +Claim_Integration_Test:test_RevertGiven_AlreadyClaimed() (gas: 267389) +Claim_Integration_Test:test_RevertGiven_CampaignExpired() (gas: 17948) +Claim_Integration_Test:test_RevertGiven_ProtocolFeeNotZero() (gas: 84992) +Clawback_Integration_Test:testFuzz_Clawback(address) (runs: 20, μ: 318053, ~: 318053) +Clawback_Integration_Test:testFuzz_Clawback_CampaignNotExpired(address) (runs: 20, μ: 89455, ~: 89455) +Clawback_Integration_Test:test_Clawback() (gas: 273235) +Clawback_Integration_Test:test_RevertGiven_CampaignNotExpired() (gas: 30549) +Constructor_MerkleStreamerLL_Integration_Test:test_Constructor() (gas: 1219550) +CreateMerkleStreamerLL_Integration_Test:testFuzz_CreateMerkleStreamerLL(address,uint40) (runs: 20, μ: 1271594, ~: 1271594) +CreateMerkleStreamerLL_Integration_Test:test_RevertGiven_AlreadyDeployed() (gas: 8937393460516730646) +CreateWithDeltas_Integration_Test:test_BatchCreateWithDeltas() (gas: 2080378) +CreateWithDurations_Integration_Test:test_BatchCreateWithDurations() (gas: 1338114) +CreateWithMilestones_Integration_Test:test_BatchCreateWithMilestones() (gas: 2075841) +CreateWithRange_Integration_Test:test_CreateWithRange() (gas: 1340637) +HasClaimed_Integration_Test:test_HasClaimed() (gas: 252210) +HasClaimed_Integration_Test:test_HasClaimed_IndexNotInTree() (gas: 7899) +HasClaimed_Integration_Test:test_HasClaimed_NotClaimed() (gas: 13156) +HasExpired_Integration_Test:test_HasExpired_ExpirationEqualToCurrentTime() (gas: 13848) +HasExpired_Integration_Test:test_HasExpired_ExpirationGreaterThanCurrentTime() (gas: 13942) +HasExpired_Integration_Test:test_HasExpired_ExpirationLessThanCurrentTime() (gas: 5637) +HasExpired_Integration_Test:test_HasExpired_ExpirationZero() (gas: 1224621) MerkleBuilder_Test:testFuzz_ComputeLeaf(uint256,address,uint128) (runs: 20, μ: 1176, ~: 1176) -MerkleBuilder_Test:testFuzz_ComputeLeaves((uint256,address,uint128)[]) (runs: 20, μ: 329364, ~: 332179) -Precompiles_Test:test_DeployBatch() (gas: 2809098) -Precompiles_Test:test_DeployMerkleStreamerFactory() (gas: 2935320) -Precompiles_Test:test_DeployPeriphery() (gas: 40999541) -Precompiles_Test:test_DeployProxyTargetApprove() (gas: 11198860) -Precompiles_Test:test_DeployProxyTargetPermit2() (gas: 13005097) -Precompiles_Test:test_DeployProxyTargetPush() (gas: 10373924) -Renounce_TargetApprove_Integration_Test:test_Renounce_LockupDynamic() (gas: 356441) -Renounce_TargetApprove_Integration_Test:test_Renounce_LockupLinear() (gas: 268998) -Renounce_TargetPermit2_Integration_Test:test_Renounce_LockupDynamic() (gas: 414030) -Renounce_TargetPermit2_Integration_Test:test_Renounce_LockupLinear() (gas: 326599) -Renounce_TargetPush_Integration_Test:test_Renounce_LockupDynamic() (gas: 347373) -Renounce_TargetPush_Integration_Test:test_Renounce_LockupLinear() (gas: 259962) -USDC_BatchCancelMultiple_TargetApprove_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 11086304, ~: 12481506) -USDC_BatchCancelMultiple_TargetPermit2_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 10074423, ~: 10730331) -USDC_BatchCancelMultiple_TargetPush_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 9529203, ~: 8589940) -USDC_BatchCreate_TargetApprove_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 44879789, ~: 46145987) -USDC_BatchCreate_TargetApprove_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1675149, ~: 1521629) -USDC_BatchCreate_TargetPermit2_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 45152074, ~: 48044873) -USDC_BatchCreate_TargetPermit2_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1844369, ~: 1948810) -USDC_BatchCreate_TargetPush_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 41352354, ~: 35401416) -USDC_BatchCreate_TargetPush_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1831920, ~: 1948267) -USDC_CreateWithMilestones_Batch_Fork_Test:testForkFuzz_CreateWithMilestones((uint128,address,address,uint128,uint40,(uint128,uint64,uint40)[])) (runs: 20, μ: 40474682, ~: 31218338) -USDC_CreateWithRange_Batch_Fork_Test:testForkFuzz_CreateWithRange((uint128,(uint40,uint40,uint40),address,address,uint128)) (runs: 20, μ: 1449211, ~: 1694983) -USDC_MerkleStreamerLL_Fork_Test:testForkFuzz_MerkleStreamerLL((address,uint40,(uint256,uint256,uint128)[],uint256)) (runs: 20, μ: 5061479, ~: 4385208) -USDT_BatchCancelMultiple_TargetApprove_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 11086304, ~: 12481506) -USDT_BatchCancelMultiple_TargetPermit2_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 10074423, ~: 10730331) -USDT_BatchCancelMultiple_TargetPush_Fork_Test:testForkFuzz_BatchCancelMultiple(uint256) (runs: 20, μ: 9529203, ~: 8589940) -USDT_BatchCreate_TargetApprove_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 44879789, ~: 46145987) -USDT_BatchCreate_TargetApprove_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1675149, ~: 1521629) -USDT_BatchCreate_TargetPermit2_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 45152074, ~: 48044873) -USDT_BatchCreate_TargetPermit2_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1844369, ~: 1948810) -USDT_BatchCreate_TargetPush_Fork_Test:testForkFuzz_BatchCreateWithMilestones((uint128,address,uint128,uint40,(uint128,uint64,uint40)[],uint256)) (runs: 20, μ: 41352354, ~: 35401416) -USDT_BatchCreate_TargetPush_Fork_Test:testForkFuzz_BatchCreateWithRange((uint128,(uint40,uint40,uint40),address,uint128,uint256)) (runs: 20, μ: 1831920, ~: 1948267) -USDT_CreateWithMilestones_Batch_Fork_Test:testForkFuzz_CreateWithMilestones((uint128,address,address,uint128,uint40,(uint128,uint64,uint40)[])) (runs: 20, μ: 40474682, ~: 31218338) -USDT_CreateWithRange_Batch_Fork_Test:testForkFuzz_CreateWithRange((uint128,(uint40,uint40,uint40),address,address,uint128)) (runs: 20, μ: 1449211, ~: 1694983) -USDT_MerkleStreamerLL_Fork_Test:testForkFuzz_MerkleStreamerLL((address,uint40,(uint256,uint256,uint128)[],uint256)) (runs: 20, μ: 5061479, ~: 4385208) -WithdrawMaxAndTransfer_TargetApprove_Integration_Test:test_WithdrawMaxAndTransfer_LockupDynamic() (gas: 398281) -WithdrawMaxAndTransfer_TargetApprove_Integration_Test:test_WithdrawMaxAndTransfer_LockupLinear() (gas: 314084) -WithdrawMaxAndTransfer_TargetPermit2_Integration_Test:test_WithdrawMaxAndTransfer_LockupDynamic() (gas: 455870) -WithdrawMaxAndTransfer_TargetPermit2_Integration_Test:test_WithdrawMaxAndTransfer_LockupLinear() (gas: 371666) -WithdrawMaxAndTransfer_TargetPush_Integration_Test:test_WithdrawMaxAndTransfer_LockupDynamic() (gas: 368368) -WithdrawMaxAndTransfer_TargetPush_Integration_Test:test_WithdrawMaxAndTransfer_LockupLinear() (gas: 284193) -WithdrawMax_TargetApprove_Integration_Test:test_WithdrawMax_Linear() (gas: 268950) -WithdrawMax_TargetApprove_Integration_Test:test_WithdrawMax_LockupDynamic() (gas: 346388) -WithdrawMax_TargetPermit2_Integration_Test:test_WithdrawMax_Linear() (gas: 326542) -WithdrawMax_TargetPermit2_Integration_Test:test_WithdrawMax_LockupDynamic() (gas: 403977) -WithdrawMax_TargetPush_Integration_Test:test_WithdrawMax_Linear() (gas: 258960) -WithdrawMax_TargetPush_Integration_Test:test_WithdrawMax_LockupDynamic() (gas: 336375) -WithdrawMultiple_TargetApprove_Integration_Test:test_WithdrawMultiple_LockupDynamic() (gas: 2374009) -WithdrawMultiple_TargetApprove_Integration_Test:test_WithdrawMultiple_LockupLinear() (gas: 1565732) -WithdrawMultiple_TargetPermit2_Integration_Test:test_WithdrawMultiple_LockupDynamic() (gas: 2431811) -WithdrawMultiple_TargetPermit2_Integration_Test:test_WithdrawMultiple_LockupLinear() (gas: 1623339) -WithdrawMultiple_TargetPush_Integration_Test:test_WithdrawMultiple_LockupDynamic() (gas: 2364941) -WithdrawMultiple_TargetPush_Integration_Test:test_WithdrawMultiple_LockupLinear() (gas: 1556623) -Withdraw_TargetApprove_Integration_Test:test_Withdraw_LockupDynamic() (gas: 369772) -Withdraw_TargetApprove_Integration_Test:test_Withdraw_LockupLinear() (gas: 288951) -Withdraw_TargetPermit2_Integration_Test:test_Withdraw_LockupDynamic() (gas: 427361) -Withdraw_TargetPermit2_Integration_Test:test_Withdraw_LockupLinear() (gas: 346533) -Withdraw_TargetPush_Integration_Test:test_Withdraw_LockupDynamic() (gas: 359759) -Withdraw_TargetPush_Integration_Test:test_Withdraw_LockupLinear() (gas: 278960) -WrapAndCreate_TargetApprove_Fork_Test:testForkFuzz_WrapAndCreateWithMilestones(uint256,uint256) (runs: 20, μ: 334175, ~: 334205) -WrapAndCreate_TargetApprove_Fork_Test:testForkFuzz_WrapAndCreateWithRange(uint256) (runs: 20, μ: 256936, ~: 256685) -WrapAndCreate_TargetApprove_Integration_Test:test_WrapAndCreateWithDeltas() (gas: 353424) -WrapAndCreate_TargetApprove_Integration_Test:test_WrapAndCreateWithDurations() (gas: 277060) -WrapAndCreate_TargetApprove_Integration_Test:test_WrapAndCreateWithMilestones() (gas: 353634) -WrapAndCreate_TargetApprove_Integration_Test:test_WrapAndCreateWithRange() (gas: 277339) -WrapAndCreate_TargetPermit2_Fork_Test:testForkFuzz_WrapAndCreateWithMilestones(uint256,uint256) (runs: 20, μ: 334205, ~: 334235) -WrapAndCreate_TargetPermit2_Fork_Test:testForkFuzz_WrapAndCreateWithRange(uint256) (runs: 20, μ: 257001, ~: 256855) -WrapAndCreate_TargetPermit2_Integration_Test:test_WrapAndCreateWithDeltas() (gas: 353454) -WrapAndCreate_TargetPermit2_Integration_Test:test_WrapAndCreateWithDurations() (gas: 277090) -WrapAndCreate_TargetPermit2_Integration_Test:test_WrapAndCreateWithMilestones() (gas: 353664) -WrapAndCreate_TargetPermit2_Integration_Test:test_WrapAndCreateWithRange() (gas: 277369) -WrapAndCreate_TargetPush_Fork_Test:testForkFuzz_WrapAndCreateWithMilestones(uint256,uint256) (runs: 20, μ: 333127, ~: 333157) -WrapAndCreate_TargetPush_Fork_Test:testForkFuzz_WrapAndCreateWithRange(uint256) (runs: 20, μ: 255855, ~: 255638) -WrapAndCreate_TargetPush_Integration_Test:test_WrapAndCreateWithDeltas() (gas: 352378) -WrapAndCreate_TargetPush_Integration_Test:test_WrapAndCreateWithDurations() (gas: 276014) -WrapAndCreate_TargetPush_Integration_Test:test_WrapAndCreateWithMilestones() (gas: 352588) -WrapAndCreate_TargetPush_Integration_Test:test_WrapAndCreateWithRange() (gas: 276293) \ No newline at end of file +MerkleBuilder_Test:testFuzz_ComputeLeaves((uint256,address,uint128)[]) (runs: 20, μ: 353773, ~: 397124) +Precompiles_Test:test_DeployBatch() (gas: 4112) +Precompiles_Test:test_DeployMerkleStreamerFactory() (gas: 4112) +Precompiles_Test:test_DeployPeriphery() (gas: 4113) +USDC_CreateWithMilestones_Batch_Fork_Test:testForkFuzz_CreateWithMilestones((uint128,address,address,uint128,uint40,(uint128,uint64,uint40)[])) (runs: 20, μ: 28155361, ~: 20377052) +USDC_CreateWithRange_Batch_Fork_Test:testForkFuzz_CreateWithRange((uint128,(uint40,uint40,uint40),address,address,uint128)) (runs: 20, μ: 1311164, ~: 1220007) +USDC_MerkleStreamerLL_Fork_Test:testForkFuzz_MerkleStreamerLL((address,uint40,(uint256,uint256,uint128)[],uint256)) (runs: 20, μ: 4487011, ~: 4030889) +USDT_CreateWithMilestones_Batch_Fork_Test:testForkFuzz_CreateWithMilestones((uint128,address,address,uint128,uint40,(uint128,uint64,uint40)[])) (runs: 20, μ: 28155361, ~: 20377052) +USDT_CreateWithRange_Batch_Fork_Test:testForkFuzz_CreateWithRange((uint128,(uint40,uint40,uint40),address,address,uint128)) (runs: 20, μ: 1311164, ~: 1220007) +USDT_MerkleStreamerLL_Fork_Test:testForkFuzz_MerkleStreamerLL((address,uint40,(uint256,uint256,uint128)[],uint256)) (runs: 20, μ: 4487011, ~: 4030889) \ No newline at end of file diff --git a/.github/workflows/create-merkle-streamer-ll.yml b/.github/workflows/create-merkle-streamer-ll.yml index e30bf7d0..c91c38fb 100644 --- a/.github/workflows/create-merkle-streamer-ll.yml +++ b/.github/workflows/create-merkle-streamer-ll.yml @@ -11,7 +11,7 @@ env: API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} FOUNDRY_PROFILE: "optimized" MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} + RPC_URL_SEPOLIA: ${{ secrets.RPC_URL_SEPOLIA }} RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} on: @@ -21,7 +21,7 @@ on: description: "Parameters needed for the script, as comma-separated tupples." required: true chain: - default: "goerli" + default: "sepolia" description: "Chain name as defined in the Foundry config." required: false diff --git a/.github/workflows/deploy-batch.yml b/.github/workflows/deploy-batch.yml index 562d81ee..55c4ae03 100644 --- a/.github/workflows/deploy-batch.yml +++ b/.github/workflows/deploy-batch.yml @@ -11,14 +11,14 @@ env: API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} FOUNDRY_PROFILE: "optimized" MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} + RPC_URL_SEPOLIA: ${{ secrets.RPC_URL_SEPOLIA }} on: workflow_dispatch: inputs: chain: - default: "goerli" + default: "sepolia" description: "Chain name as defined in the Foundry config." required: false diff --git a/.github/workflows/deploy-merkle-streamer-factory.yml b/.github/workflows/deploy-merkle-streamer-factory.yml index 666dd8d0..902ab58e 100644 --- a/.github/workflows/deploy-merkle-streamer-factory.yml +++ b/.github/workflows/deploy-merkle-streamer-factory.yml @@ -11,14 +11,14 @@ env: API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} FOUNDRY_PROFILE: "optimized" MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} + RPC_URL_SEPOLIA: ${{ secrets.RPC_URL_SEPOLIA }} on: workflow_dispatch: inputs: chain: - default: "goerli" + default: "sepolia" description: "Chain name as defined in the Foundry config." required: false diff --git a/.github/workflows/deploy-periphery.yml b/.github/workflows/deploy-periphery.yml index 57ef2671..02be7007 100644 --- a/.github/workflows/deploy-periphery.yml +++ b/.github/workflows/deploy-periphery.yml @@ -11,20 +11,16 @@ env: API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} FOUNDRY_PROFILE: "optimized" MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} + RPC_URL_SEPOLIA: ${{ secrets.RPC_URL_SEPOLIA }} on: workflow_dispatch: inputs: chain: - default: "goerli" + default: "sepolia" description: "Chain name as defined in the Foundry config." required: false - permit2: - default: "0x000000000022D473030F116dDEE9F6B43aC78BA3" - description: "The address of the Permit2 contract." - required: false jobs: @@ -44,10 +40,9 @@ jobs: forge script script/DeployPeriphery.s.sol --broadcast --rpc-url "${{ inputs.chain }}" - --sig "run(address)" + --sig "run()" --verify -vvvv - "${{ inputs.permit2 }}" - name: "Add workflow summary" run: | diff --git a/.github/workflows/deploy-protocol.yml b/.github/workflows/deploy-protocol.yml index e9b16f5b..21bfd792 100644 --- a/.github/workflows/deploy-protocol.yml +++ b/.github/workflows/deploy-protocol.yml @@ -12,8 +12,8 @@ env: FOUNDRY_OPTIMIZER_RUNS: "1000" # needed to compile V2 Core FOUNDRY_PROFILE: "optimized" MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} + RPC_URL_SEPOLIA: ${{ secrets.RPC_URL_SEPOLIA }} on: workflow_dispatch: @@ -23,17 +23,13 @@ on: description: "Initial protocol admin." required: false chain: - default: "goerli" + default: "sepolia" description: "Chain name as defined in the Foundry config." required: false max-segment-count: 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: @@ -52,12 +48,11 @@ jobs: forge script script/DeployProtocol.s.sol --broadcast --rpc-url "${{ inputs.chain }}" - --sig "run(address,uint256,address)" + --sig "run(address,uint256)" --verify -vvvv "${{ inputs.admin }}" "${{ inputs.max-segment-count }}" - "${{ inputs.permit2 }}" - name: "Add workflow summary" run: | diff --git a/.github/workflows/deploy-proxy-target-approve.yml b/.github/workflows/deploy-proxy-target-approve.yml deleted file mode 100644 index f93433e2..00000000 --- a/.github/workflows/deploy-proxy-target-approve.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: "Deploy ProxyTargetApprove" - -env: - API_KEY_ARBISCAN: ${{ secrets.API_KEY_ARBISCAN }} - API_KEY_BSCSCAN: ${{ secrets.API_KEY_BSCSCAN }} - API_KEY_ETHERSCAN: ${{ secrets.API_KEY_ETHERSCAN }} - API_KEY_GNOSISSCAN: ${{ secrets.API_KEY_GNOSISSCAN }} - API_KEY_INFURA: ${{ secrets.API_KEY_INFURA }} - API_KEY_OPTIMISTIC_ETHERSCAN: ${{ secrets.API_KEY_OPTIMISTIC_ETHERSCAN }} - API_KEY_POLYGONSCAN: ${{ secrets.API_KEY_POLYGONSCAN }} - API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} - FOUNDRY_PROFILE: "optimized" - MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} - RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} - -on: - workflow_dispatch: - inputs: - chain: - default: "goerli" - description: "Chain name as defined in the Foundry config." - required: false - -jobs: - deploy-proxy-target-approve: - runs-on: "ubuntu-latest" - steps: - - name: "Check out the repo" - uses: "actions/checkout@v3" - with: - submodules: "recursive" - - - name: "Install Foundry" - uses: "foundry-rs/foundry-toolchain@v1" - - - name: "Deploy the SablierV2ProxyTargetApprove contract" - run: >- - forge script script/DeployProxyTargetApprove.s.sol - --broadcast - --rpc-url "${{ inputs.chain }}" - --sig "run()" - --verify - -vvvv - - - name: "Add workflow summary" - run: | - echo "## Result" >> $GITHUB_STEP_SUMMARY - echo "✅ Done" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/deploy-proxy-target-permit2.yml b/.github/workflows/deploy-proxy-target-permit2.yml deleted file mode 100644 index 2cfed68c..00000000 --- a/.github/workflows/deploy-proxy-target-permit2.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: "Deploy ProxyTargetPermit2" - -env: - API_KEY_ARBISCAN: ${{ secrets.API_KEY_ARBISCAN }} - API_KEY_BSCSCAN: ${{ secrets.API_KEY_BSCSCAN }} - API_KEY_ETHERSCAN: ${{ secrets.API_KEY_ETHERSCAN }} - API_KEY_GNOSISSCAN: ${{ secrets.API_KEY_GNOSISSCAN }} - API_KEY_INFURA: ${{ secrets.API_KEY_INFURA }} - API_KEY_OPTIMISTIC_ETHERSCAN: ${{ secrets.API_KEY_OPTIMISTIC_ETHERSCAN }} - API_KEY_POLYGONSCAN: ${{ secrets.API_KEY_POLYGONSCAN }} - API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} - FOUNDRY_PROFILE: "optimized" - MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} - RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} - -on: - workflow_dispatch: - inputs: - chain: - 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-permit2: - runs-on: "ubuntu-latest" - steps: - - name: "Check out the repo" - uses: "actions/checkout@v3" - with: - submodules: "recursive" - - - name: "Install Foundry" - uses: "foundry-rs/foundry-toolchain@v1" - - - name: "Deploy the SablierV2ProxyTargetPermit2 contract" - run: >- - forge script script/DeployProxyTargetPermit2.s.sol - --broadcast - --rpc-url "${{ inputs.chain }}" - --sig "run(address)" - --verify - -vvvv - "${{ inputs.permit2 }}" - - - name: "Add workflow summary" - run: | - echo "## Result" >> $GITHUB_STEP_SUMMARY - echo "✅ Done" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/deploy-proxy-target-push.yml b/.github/workflows/deploy-proxy-target-push.yml deleted file mode 100644 index 05545bd3..00000000 --- a/.github/workflows/deploy-proxy-target-push.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: "Deploy ProxyTargetPush" - -env: - API_KEY_ARBISCAN: ${{ secrets.API_KEY_ARBISCAN }} - API_KEY_BSCSCAN: ${{ secrets.API_KEY_BSCSCAN }} - API_KEY_ETHERSCAN: ${{ secrets.API_KEY_ETHERSCAN }} - API_KEY_GNOSISSCAN: ${{ secrets.API_KEY_GNOSISSCAN }} - API_KEY_INFURA: ${{ secrets.API_KEY_INFURA }} - API_KEY_OPTIMISTIC_ETHERSCAN: ${{ secrets.API_KEY_OPTIMISTIC_ETHERSCAN }} - API_KEY_POLYGONSCAN: ${{ secrets.API_KEY_POLYGONSCAN }} - API_KEY_SNOWTRACE: ${{ secrets.API_KEY_SNOWTRACE }} - FOUNDRY_PROFILE: "optimized" - MNEMONIC: ${{ secrets.MNEMONIC }} - RPC_URL_GOERLI: ${{ secrets.RPC_URL_GOERLI }} - RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} - -on: - workflow_dispatch: - inputs: - chain: - default: "goerli" - description: "Chain name as defined in the Foundry config." - required: false - -jobs: - deploy-proxy-target-push: - runs-on: "ubuntu-latest" - steps: - - name: "Check out the repo" - uses: "actions/checkout@v3" - with: - submodules: "recursive" - - - name: "Install Foundry" - uses: "foundry-rs/foundry-toolchain@v1" - - - name: "Deploy the SablierV2ProxyTargetPush contract" - run: >- - forge script script/DeployProxyTargetPush.s.sol - --broadcast - --rpc-url "${{ inputs.chain }}" - --sig "run()" - --verify - -vvvv - - - name: "Add workflow summary" - run: | - echo "## Result" >> $GITHUB_STEP_SUMMARY - echo "✅ Done" >> $GITHUB_STEP_SUMMARY diff --git a/.gitmodules b/.gitmodules index 28ff1bd8..dc5d6b80 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,14 +6,6 @@ branch = "release-v4.9" path = "lib/openzeppelin-contracts" url = "https://github.com/OpenZeppelin/openzeppelin-contracts" -[submodule "lib/permit2"] - branch = "main" - path = "lib/permit2" - url = "https://github.com/uniswap/permit2" -[submodule "lib/prb-proxy"] - branch = "release-v4" - path = "lib/prb-proxy" - url = "https://github.com/PaulRBerg/prb-proxy" [submodule "lib/prb-test"] branch = "release-v0" path = "lib/prb-test" diff --git a/foundry.toml b/foundry.toml index 1f424036..53a009a0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,14 +1,10 @@ [profile.default] auto_detect_solc = false - block_timestamp = 1_682_899_200 # May 1, 2023 at 00:00 GMT + block_timestamp = 1_682_899_200 # May 1, 2023 at 00:00 GMT bytecode_hash = "none" evm_version = "paris" fs_permissions = [{ access = "read", path = "out-optimized" }] - gas_reports = [ - "SablierV2MerkleStreamerFactory", - "SablierV2MerkleStreamerLL", - "SablierV2ProxyTarget", - ] + gas_reports = ["SablierV2MerkleStreamerFactory", "SablierV2MerkleStreamerLL"] libs = ["lib"] optimizer = true optimizer_runs = 10_000 @@ -73,4 +69,4 @@ mainnet = "${RPC_URL_MAINNET}" optimism = "https://optimism-mainnet.infura.io/v3/${API_KEY_INFURA}" polygon = "https://polygon-mainnet.infura.io/v3/${API_KEY_INFURA}" - sepolia = "https://sepolia.infura.io/v3/${API_KEY_INFURA}" + sepolia = "${RPC_URL_SEPOLIA}" diff --git a/lib/permit2 b/lib/permit2 deleted file mode 160000 index cc56ad0f..00000000 --- a/lib/permit2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cc56ad0f3439c502c246fc5cfcc3db92bb8b7219 diff --git a/lib/prb-proxy b/lib/prb-proxy deleted file mode 160000 index 972afc98..00000000 --- a/lib/prb-proxy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 972afc98c7d85e54fe021c6bc252f47030eb8d62 diff --git a/package.json b/package.json index 4116ac16..50d1bbbb 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,7 @@ }, "dependencies": { "@openzeppelin/contracts": "4.9.2", - "@prb/proxy": "4.0.1", - "@sablier/v2-core": "1.0.2", - "@uniswap/permit2": "github:Uniswap/permit2#cc56ad0f3439c502c246fc5cfcc3db92bb8b7219" + "@sablier/v2-core": "1.0.2" }, "devDependencies": { "prettier": "^2.8.8", @@ -46,7 +44,6 @@ "web3" ], "peerDependencies": { - "@prb/proxy": "4.0.1", "@sablier/v2-core": "1.0.2" }, "publishConfig": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6085a9b0..8080b5fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,9 @@ dependencies: '@openzeppelin/contracts': specifier: 4.9.2 version: 4.9.2 - '@prb/proxy': - specifier: 4.0.1 - version: 4.0.1 '@sablier/v2-core': specifier: 1.0.2 version: 1.0.2(@openzeppelin/contracts@4.9.2)(@prb/math@4.0.1) - '@uniswap/permit2': - specifier: github:Uniswap/permit2#cc56ad0f3439c502c246fc5cfcc3db92bb8b7219 - version: github.com/Uniswap/permit2/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219 devDependencies: prettier: @@ -57,10 +51,6 @@ packages: resolution: {integrity: sha512-ANTz2KMV+dMdZ57mWgDTR6jZo5uQzUczQEHCxd7CvJZZ9yafnfPhUUILHvvigIOZ85fZbTPVkC8YoRG1z5Qf7g==} dev: false - /@prb/proxy@4.0.1: - resolution: {integrity: sha512-uphCpNzkhT3aKia5/KKJz2eHyeYGnJeiFt3IeehtylaXxfOK3iS1bsxljyR+XjtzldSA6aWtiKg0MnhEHw/IWg==} - dev: false - /@sablier/v2-core@1.0.2(@openzeppelin/contracts@4.9.2)(@prb/math@4.0.1): resolution: {integrity: sha512-BjobBTRLuh38fQsHtFGVsQI1XN9JXatldxbS+aFxlhYaU77fQimCejYrBqP7W1wQZnBAvdXRdKNPUskdUpM5nw==} peerDependencies: @@ -492,9 +482,3 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - - github.com/Uniswap/permit2/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219: - resolution: {tarball: https://codeload.github.com/Uniswap/permit2/tar.gz/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219} - name: '@uniswap/permit2' - version: 1.0.0 - dev: false diff --git a/remappings.txt b/remappings.txt index 83a99577..95c5a1d9 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,11 +1,7 @@ @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ -@prb/proxy/=lib/prb-proxy/ -@prb/proxy-test/=lib/prb-proxy/test/ @prb/test/=lib/prb-test/src/ @sablier/v2-core/=lib/v2-core/ @sablier/v2-core-script/=lib/v2-core/script/ @sablier/v2-core-test/=lib/v2-core/test/ -@uniswap/permit2/=lib/permit2/src/ -@uniswap/permit2-test/=lib/permit2/test/ forge-std/=lib/forge-std/src/ solady/=lib/solady/src/ diff --git a/script/DeployDeterministicPeriphery.s.sol b/script/DeployDeterministicPeriphery.s.sol index 1e310991..425ac3e3 100644 --- a/script/DeployDeterministicPeriphery.s.sol +++ b/script/DeployDeterministicPeriphery.s.sol @@ -2,50 +2,26 @@ pragma solidity >=0.8.19 <0.9.0; import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { SablierV2Batch } from "../src/SablierV2Batch.sol"; import { SablierV2MerkleStreamerFactory } from "../src/SablierV2MerkleStreamerFactory.sol"; -import { SablierV2ProxyTargetApprove } from "../src/SablierV2ProxyTargetApprove.sol"; -import { SablierV2ProxyTargetPermit2 } from "../src/SablierV2ProxyTargetPermit2.sol"; -import { SablierV2ProxyTargetPush } from "../src/SablierV2ProxyTargetPush.sol"; /// @notice Deploys all V2 Periphery contracts at deterministic addresses across chains, in the following order: /// /// 1. {SablierV2Batch} /// 2. {SablierV2MerkleStreamerFactory} -/// 3. {SablierV2ProxyTargetApprove} -/// 4. {SablierV2ProxyTargetPermit2} -/// 5. {SablierV2ProxyTargetPush} /// /// @dev Reverts if any contract has already been deployed. contract DeployDeterministicPeriphery is BaseScript { - struct DeployedContracts { - SablierV2Batch batch; - SablierV2MerkleStreamerFactory merkleStreamerFactory; - SablierV2ProxyTargetApprove targetApprove; - SablierV2ProxyTargetPermit2 targetPermit2; - SablierV2ProxyTargetPush targetPush; - } - /// @dev The presence of the salt instructs Forge to deploy the contract via a deterministic CREATE2 factory. /// https://github.com/Arachnid/deterministic-deployment-proxy - function run( - string memory create2Salt, - IAllowanceTransfer permit2 - ) + function run(string memory create2Salt) public virtual broadcast - returns (DeployedContracts memory deployedContracts) + returns (SablierV2Batch batch, SablierV2MerkleStreamerFactory merkleStreamerFactory) { - deployedContracts.batch = new SablierV2Batch{ salt: bytes32(abi.encodePacked(create2Salt)) }(); - deployedContracts.merkleStreamerFactory = - new SablierV2MerkleStreamerFactory{ salt: bytes32(abi.encodePacked(create2Salt)) }(); - deployedContracts.targetApprove = - new SablierV2ProxyTargetApprove{ salt: bytes32(abi.encodePacked(create2Salt)) }(); - deployedContracts.targetPermit2 = - new SablierV2ProxyTargetPermit2{ salt: bytes32(abi.encodePacked(create2Salt)) }(permit2); - deployedContracts.targetPush = new SablierV2ProxyTargetPush{ salt: bytes32(abi.encodePacked(create2Salt)) }(); + batch = new SablierV2Batch{ salt: bytes32(abi.encodePacked(create2Salt)) }(); + merkleStreamerFactory = new SablierV2MerkleStreamerFactory{ salt: bytes32(abi.encodePacked(create2Salt)) }(); } } diff --git a/script/DeployDeterministicProxyTargetApprove.s.sol b/script/DeployDeterministicProxyTargetApprove.s.sol deleted file mode 100644 index 30f41ab4..00000000 --- a/script/DeployDeterministicProxyTargetApprove.s.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; - -import { SablierV2ProxyTargetApprove } from "../src/SablierV2ProxyTargetApprove.sol"; - -/// @notice Deploys {SablierV2ProxyTargetApprove} at a deterministic address across chains. -/// @dev Reverts if the contract has already been deployed. -contract DeployDeterministicProxyTargetApprove 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(string memory create2Salt) - public - virtual - broadcast - returns (SablierV2ProxyTargetApprove targetApprove) - { - targetApprove = new SablierV2ProxyTargetApprove{ salt: bytes32(abi.encodePacked(create2Salt)) }(); - } -} diff --git a/script/DeployDeterministicProxyTargetPermit2.s.sol b/script/DeployDeterministicProxyTargetPermit2.s.sol deleted file mode 100644 index a5e1f469..00000000 --- a/script/DeployDeterministicProxyTargetPermit2.s.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; - -import { SablierV2ProxyTargetPermit2 } from "../src/SablierV2ProxyTargetPermit2.sol"; - -/// @notice Deploys {SablierV2ProxyTargetPermit2} at a deterministic address across chains. -/// @dev Reverts if the contract has already been deployed. -contract DeployDeterministicProxyTargetPermit2 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( - string memory create2Salt, - IAllowanceTransfer permit2 - ) - public - virtual - broadcast - returns (SablierV2ProxyTargetPermit2 targetPermit2) - { - targetPermit2 = new SablierV2ProxyTargetPermit2{ salt: bytes32(abi.encodePacked(create2Salt)) }(permit2); - } -} diff --git a/script/DeployDeterministicProxyTargetPush.s.sol b/script/DeployDeterministicProxyTargetPush.s.sol deleted file mode 100644 index 99971505..00000000 --- a/script/DeployDeterministicProxyTargetPush.s.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; - -import { SablierV2ProxyTargetPush } from "../src/SablierV2ProxyTargetPush.sol"; - -/// @notice Deploys {SablierV2ProxyTargetApprove} at a deterministic address across chains. -/// @dev Reverts if the contract has already been deployed. -contract DeployDeterministicProxyTargetPush 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(string memory create2Salt) public virtual broadcast returns (SablierV2ProxyTargetPush targetPush) { - targetPush = new SablierV2ProxyTargetPush{ salt: bytes32(abi.encodePacked(create2Salt)) }(); - } -} diff --git a/script/DeployPeriphery.s.sol b/script/DeployPeriphery.s.sol index 9d6fd811..09033d52 100644 --- a/script/DeployPeriphery.s.sol +++ b/script/DeployPeriphery.s.sol @@ -2,37 +2,21 @@ pragma solidity >=0.8.19 <0.9.0; import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { SablierV2MerkleStreamerFactory } from "../src/SablierV2MerkleStreamerFactory.sol"; import { SablierV2Batch } from "../src/SablierV2Batch.sol"; -import { SablierV2ProxyTargetApprove } from "../src/SablierV2ProxyTargetApprove.sol"; -import { SablierV2ProxyTargetPermit2 } from "../src/SablierV2ProxyTargetPermit2.sol"; -import { SablierV2ProxyTargetPush } from "../src/SablierV2ProxyTargetPush.sol"; /// @notice Deploys all V2 Periphery contract in the following order: /// /// 1. {SablierV2Batch} /// 2. {SablierV2MerkleStreamerFactory} -/// 3. {SablierV2ProxyTargetApprove} -/// 4. {SablierV2ProxyTargetPermit2} -/// 5. {SablierV2ProxyTargetPush} contract DeployPeriphery is BaseScript { - function run(IAllowanceTransfer permit2) + function run() public broadcast - returns ( - SablierV2Batch batch, - SablierV2MerkleStreamerFactory merkleStreamerFactory, - SablierV2ProxyTargetApprove targetApprove, - SablierV2ProxyTargetPermit2 targetPermit2, - SablierV2ProxyTargetPush targetPush - ) + returns (SablierV2Batch batch, SablierV2MerkleStreamerFactory merkleStreamerFactory) { batch = new SablierV2Batch(); merkleStreamerFactory = new SablierV2MerkleStreamerFactory(); - targetApprove = new SablierV2ProxyTargetApprove(); - targetPermit2 = new SablierV2ProxyTargetPermit2(permit2); - targetPush = new SablierV2ProxyTargetPush(); } } diff --git a/script/DeployProtocol.s.sol b/script/DeployProtocol.s.sol index 79004978..7833bd70 100644 --- a/script/DeployProtocol.s.sol +++ b/script/DeployProtocol.s.sol @@ -6,20 +6,15 @@ import { SablierV2LockupDynamic } from "@sablier/v2-core/src/SablierV2LockupDyna import { SablierV2LockupLinear } from "@sablier/v2-core/src/SablierV2LockupLinear.sol"; import { SablierV2NFTDescriptor } from "@sablier/v2-core/src/SablierV2NFTDescriptor.sol"; import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { SablierV2MerkleStreamerFactory } from "../src/SablierV2MerkleStreamerFactory.sol"; import { SablierV2Batch } from "../src/SablierV2Batch.sol"; -import { SablierV2ProxyTargetApprove } from "../src/SablierV2ProxyTargetApprove.sol"; -import { SablierV2ProxyTargetPermit2 } from "../src/SablierV2ProxyTargetPermit2.sol"; -import { SablierV2ProxyTargetPush } from "../src/SablierV2ProxyTargetPush.sol"; /// @notice Deploys the Sablier V2 Protocol. contract DeployProtocol is BaseScript { function run( address initialAdmin, - uint256 maxSegmentCount, - IAllowanceTransfer permit2 + uint256 maxSegmentCount ) public virtual @@ -30,10 +25,7 @@ contract DeployProtocol is BaseScript { SablierV2LockupLinear lockupLinear, SablierV2NFTDescriptor nftDescriptor, SablierV2Batch batch, - SablierV2MerkleStreamerFactory merkleStreamerFactory, - SablierV2ProxyTargetApprove targetApprove, - SablierV2ProxyTargetPermit2 targetPermit2, - SablierV2ProxyTargetPush targetPush + SablierV2MerkleStreamerFactory merkleStreamerFactory ) { // Deploy V2 Core. @@ -44,8 +36,5 @@ contract DeployProtocol is BaseScript { batch = new SablierV2Batch(); merkleStreamerFactory = new SablierV2MerkleStreamerFactory(); - targetApprove = new SablierV2ProxyTargetApprove(); - targetPermit2 = new SablierV2ProxyTargetPermit2(permit2); - targetPush = new SablierV2ProxyTargetPush(); } } diff --git a/script/DeployProxyTargetApprove.s.sol b/script/DeployProxyTargetApprove.s.sol deleted file mode 100644 index b61b6c5e..00000000 --- a/script/DeployProxyTargetApprove.s.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; - -import { SablierV2ProxyTargetApprove } from "../src/SablierV2ProxyTargetApprove.sol"; - -contract DeployProxyTargetApprove is BaseScript { - function run() public broadcast returns (SablierV2ProxyTargetApprove targetApprove) { - targetApprove = new SablierV2ProxyTargetApprove(); - } -} diff --git a/script/DeployProxyTargetPermit2.s.sol b/script/DeployProxyTargetPermit2.s.sol deleted file mode 100644 index 8a7f68ac..00000000 --- a/script/DeployProxyTargetPermit2.s.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; - -import { SablierV2ProxyTargetPermit2 } from "../src/SablierV2ProxyTargetPermit2.sol"; - -contract DeployProxyTargetPermit2 is BaseScript { - function run(IAllowanceTransfer permit2) public broadcast returns (SablierV2ProxyTargetPermit2 targetPermit2) { - targetPermit2 = new SablierV2ProxyTargetPermit2(permit2); - } -} diff --git a/script/DeployProxyTargetPush.s.sol b/script/DeployProxyTargetPush.s.sol deleted file mode 100644 index b1475759..00000000 --- a/script/DeployProxyTargetPush.s.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { BaseScript } from "@sablier/v2-core-script/Base.s.sol"; - -import { SablierV2ProxyTargetPush } from "../src/SablierV2ProxyTargetPush.sol"; - -contract DeployProxyTargetPush is BaseScript { - function run() public broadcast returns (SablierV2ProxyTargetPush targetPush) { - targetPush = new SablierV2ProxyTargetPush(); - } -} diff --git a/shell/prepare-artifacts.sh b/shell/prepare-artifacts.sh index 50c239b1..671063fa 100755 --- a/shell/prepare-artifacts.sh +++ b/shell/prepare-artifacts.sh @@ -18,7 +18,6 @@ rm -rf $artifacts mkdir $artifacts \ "$artifacts/interfaces" \ "$artifacts/interfaces/erc20" \ - "$artifacts/interfaces/permit2" \ "$artifacts/libraries" # Generate the artifacts with Forge @@ -28,22 +27,14 @@ FOUNDRY_PROFILE=optimized forge build cp out-optimized/SablierV2Batch.sol/SablierV2Batch.json $artifacts cp out-optimized/SablierV2MerkleStreamerFactory.sol/SablierV2MerkleStreamerFactory.json $artifacts cp out-optimized/SablierV2MerkleStreamerLL.sol/SablierV2MerkleStreamerLL.json $artifacts -cp out-optimized/SablierV2ProxyTargetApprove.sol/SablierV2ProxyTargetApprove.json $artifacts -cp out-optimized/SablierV2ProxyTargetPermit2.sol/SablierV2ProxyTargetPermit2.json $artifacts -cp out-optimized/SablierV2ProxyTargetPush.sol/SablierV2ProxyTargetPush.json $artifacts interfaces=./artifacts/interfaces cp out-optimized/ISablierV2Batch.sol/ISablierV2Batch.json $interfaces cp out-optimized/ISablierV2MerkleStreamerFactory.sol/ISablierV2MerkleStreamerFactory.json $interfaces cp out-optimized/ISablierV2MerkleStreamerLL.sol/ISablierV2MerkleStreamerLL.json $interfaces -cp out-optimized/ISablierV2ProxyTarget.sol/ISablierV2ProxyTarget.json $interfaces erc20=./artifacts/interfaces/erc20 cp out-optimized/IERC20.sol/IERC20.json $erc20 -cp out-optimized/IWrappedNativeAsset.sol/IWrappedNativeAsset.json $erc20 - -permit2=./artifacts/interfaces/permit2 -cp out-optimized/IAllowanceTransfer.sol/IAllowanceTransfer.json $permit2 libraries=./artifacts/libraries cp out-optimized/Errors.sol/Errors.json $libraries diff --git a/shell/update-precompiles.sh b/shell/update-precompiles.sh index f57fa41c..b2a9602a 100755 --- a/shell/update-precompiles.sh +++ b/shell/update-precompiles.sh @@ -14,9 +14,6 @@ FOUNDRY_PROFILE=optimized forge build # Retrieve the raw bytecodes, removing the "0x" prefix batch=$(cat out-optimized/SablierV2Batch.sol/SablierV2Batch.json | jq -r '.bytecode.object' | cut -c 3-) merkle_streamer_factory=$(cat out-optimized/SablierV2MerkleStreamerFactory.sol/SablierV2MerkleStreamerFactory.json | jq -r '.bytecode.object' | cut -c 3-) -proxy_target_approve=$(cat out-optimized/SablierV2ProxyTargetApprove.sol/SablierV2ProxyTargetApprove.json | jq -r '.bytecode.object' | cut -c 3-) -proxy_target_permit2=$(cat out-optimized/SablierV2ProxyTargetPermit2.sol/SablierV2ProxyTargetPermit2.json | jq -r '.bytecode.object' | cut -c 3-) -proxy_target_push=$(cat out-optimized/SablierV2ProxyTargetPush.sol/SablierV2ProxyTargetPush.json | jq -r '.bytecode.object' | cut -c 3-) precompiles_path="test/utils/Precompiles.sol" if [ ! -f $precompiles_path ]; then @@ -27,9 +24,6 @@ fi # Replace the current bytecodes sd "(BYTECODE_BATCH =)[^;]+;" "\$1 hex\"$batch\";" $precompiles_path sd "(BYTECODE_MERKLE_STREAMER_FACTORY =)[^;]+;" "\$1 hex\"$merkle_streamer_factory\";" $precompiles_path -sd "(BYTECODE_PROXY_TARGET_APPROVE =)[^;]+;" "\$1 hex\"$proxy_target_approve\";" $precompiles_path -sd "(BYTECODE_PROXY_TARGET_PERMIT2 =)[^;]+;" "\$1 hex\"$proxy_target_permit2\";" $precompiles_path -sd "(BYTECODE_PROXY_TARGET_PUSH =)[^;]+;" "\$1 hex\"$proxy_target_push\";" $precompiles_path # Reformat the code with Forge forge fmt $precompiles_path diff --git a/src/SablierV2ProxyTargetApprove.sol b/src/SablierV2ProxyTargetApprove.sol deleted file mode 100644 index 99e5c35b..00000000 --- a/src/SablierV2ProxyTargetApprove.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -import { SablierV2ProxyTarget } from "./abstracts/SablierV2ProxyTarget.sol"; - -/// @title SablierV2ProxyTargetApprove -/// @notice Proxy target contract that implements the transfer logic using standard ERC-20 approvals. -contract SablierV2ProxyTargetApprove is SablierV2ProxyTarget { - using SafeERC20 for IERC20; - - /// @notice Transfers the given `amount` of `asset` to the Sablier contract using standard the ERC-20 - /// approve and transfer flow, and then approves Sablier to spend the funds. - /// @dev The `transferData` data is ignored in this implementation. - function _handleTransfer( - address sablierContract, - IERC20 asset, - uint160 amount, - bytes calldata /* transferData */ - ) - internal - override - { - // Retrieve the proxy owner. - address owner = _getOwner(); - - // Transfer funds from the proxy owner to the proxy. - asset.safeTransferFrom({ from: owner, to: address(this), value: amount }); - - // Approve the Sablier contract to spend funds. - _approve(sablierContract, asset, amount); - } -} diff --git a/src/SablierV2ProxyTargetPermit2.sol b/src/SablierV2ProxyTargetPermit2.sol deleted file mode 100644 index fc14eea9..00000000 --- a/src/SablierV2ProxyTargetPermit2.sol +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; - -import { SablierV2ProxyTarget } from "./abstracts/SablierV2ProxyTarget.sol"; -import { Permit2Params } from "./types/Permit2.sol"; - -/// @title SablierV2ProxyTargetPermit2 -/// @notice Proxy target contract that implements the transfer logic using Permit2. -/// @dev See https://github.com/Uniswap/permit2. -contract SablierV2ProxyTargetPermit2 is SablierV2ProxyTarget { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - IAllowanceTransfer internal immutable PERMIT2; - - /*////////////////////////////////////////////////////////////////////////// - CONSTRUCTOR - //////////////////////////////////////////////////////////////////////////*/ - - constructor(IAllowanceTransfer permit2) { - PERMIT2 = permit2; - } - - /// @notice Transfers the given `amount` of `asset` to the Sablier contract using Permit2, and then approves Sablier - /// to spend the funds. - /// @dev The parameter `transferData` contains an ABI-encoded struct that encapsulates the parameters needed for - /// Permit2. - function _handleTransfer( - address sablierContract, - IERC20 asset, - uint160 amount, - bytes calldata transferData - ) - internal - override - { - // Decode the Permit2 parameters. - Permit2Params memory permit2Params = abi.decode(transferData, (Permit2Params)); - - // Retrieve the proxy owner. - address owner = _getOwner(); - - // Permit the proxy to spend funds from the proxy owner. - PERMIT2.permit({ owner: owner, permitSingle: permit2Params.permitSingle, signature: permit2Params.signature }); - - // Transfer funds from the proxy owner to the proxy. - PERMIT2.transferFrom({ from: owner, to: address(this), amount: amount, token: address(asset) }); - - // Approve the Sablier contract to spend funds. - _approve(sablierContract, asset, amount); - } -} diff --git a/src/SablierV2ProxyTargetPush.sol b/src/SablierV2ProxyTargetPush.sol deleted file mode 100644 index 40a9cc06..00000000 --- a/src/SablierV2ProxyTargetPush.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import { SablierV2ProxyTarget } from "./abstracts/SablierV2ProxyTarget.sol"; - -/// @title SablierV2ProxyTargetPush -/// @notice Proxy target contract that implements a push-based model for transferring funds. -contract SablierV2ProxyTargetPush is SablierV2ProxyTarget { - /// @notice The name of this function is a bit misleading, as it does not actually transfer assets to the proxy. That - /// is left for the user to do. Instead, this function only approves the Sablier contract to spend the funds. Still, - /// the name is retained so that the logic defined in {SablierV2ProxyTarget} can be reused. - /// @dev The `transferData` data is ignored in this implementation. - function _handleTransfer( - address sablierContract, - IERC20 asset, - uint160 amount, - bytes calldata /* transferData */ - ) - internal - override - { - // Approve the Sablier contract to spend funds. - _approve(sablierContract, asset, amount); - } -} diff --git a/src/abstracts/OnlyDelegateCall.sol b/src/abstracts/OnlyDelegateCall.sol deleted file mode 100644 index c1bc7013..00000000 --- a/src/abstracts/OnlyDelegateCall.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { Errors } from "../libraries/Errors.sol"; - -/// @title OnlyDelegateCall -/// @notice This contract implements logic to allow only delegate calls. -abstract contract OnlyDelegateCall { - /// @dev The address of the original contract that was deployed. - address private immutable ORIGINAL; - - /// @dev Sets the original contract address. - constructor() { - ORIGINAL = address(this); - } - - /// @notice Allows only delegate calls. - modifier onlyDelegateCall() { - _allowOnlyDelegateCall(); - _; - } - - /// @dev This function checks whether the current call is a delegate call, and reverts if it is not. - /// - /// - A private function is used instead of inlining this logic in a modifier because Solidity copies modifiers into - /// every function that uses them. The `ORIGINAL` address would get copied in every place the modifier is used, - /// which would increase the contract size. By using a function instead, we can avoid this duplication of code - /// and reduce the overall size of the contract. - function _allowOnlyDelegateCall() private view { - if (address(this) == ORIGINAL) { - revert Errors.CallNotDelegateCall(); - } - } -} diff --git a/src/abstracts/SablierV2ProxyTarget.sol b/src/abstracts/SablierV2ProxyTarget.sol deleted file mode 100644 index 1bc81625..00000000 --- a/src/abstracts/SablierV2ProxyTarget.sol +++ /dev/null @@ -1,708 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { ISablierV2LockupLinear } from "@sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol"; -import { ISablierV2LockupDynamic } from "@sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { OnlyDelegateCall } from "./OnlyDelegateCall.sol"; -import { ISablierV2ProxyTarget } from "../interfaces/ISablierV2ProxyTarget.sol"; -import { IWrappedNativeAsset } from "../interfaces/IWrappedNativeAsset.sol"; -import { Errors } from "../libraries/Errors.sol"; -import { Batch } from "../types/DataTypes.sol"; - -/* - -███████╗ █████╗ ██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗██████╗ -██╔════╝██╔══██╗██╔══██╗██║ ██║██╔════╝██╔══██╗ ██║ ██║╚════██╗ -███████╗███████║██████╔╝██║ ██║█████╗ ██████╔╝ ██║ ██║ █████╔╝ -╚════██║██╔══██║██╔══██╗██║ ██║██╔══╝ ██╔══██╗ ╚██╗ ██╔╝██╔═══╝ -███████║██║ ██║██████╔╝███████╗██║███████╗██║ ██║ ╚████╔╝ ███████╗ -╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝ - -██████╗ ██████╗ ██████╗ ██╗ ██╗██╗ ██╗ ████████╗ █████╗ ██████╗ ██████╗ ███████╗████████╗ -██╔══██╗██╔══██╗██╔═══██╗╚██╗██╔╝╚██╗ ██╔╝ ╚══██╔══╝██╔══██╗██╔══██╗██╔════╝ ██╔════╝╚══██╔══╝ -██████╔╝██████╔╝██║ ██║ ╚███╔╝ ╚████╔╝ ██║ ███████║██████╔╝██║ ███╗█████╗ ██║ -██╔═══╝ ██╔══██╗██║ ██║ ██╔██╗ ╚██╔╝ ██║ ██╔══██║██╔══██╗██║ ██║██╔══╝ ██║ -██║ ██║ ██║╚██████╔╝██╔╝ ██╗ ██║ ██║ ██║ ██║██║ ██║╚██████╔╝███████╗ ██║ -╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ - -*/ - -/// @title SablierV2ProxyTarget -/// @notice See the documentation in {ISablierV2ProxyTarget}. -abstract contract SablierV2ProxyTarget is - ISablierV2ProxyTarget, // 0 inherited components - OnlyDelegateCall // 0 inherited components -{ - using SafeERC20 for IERC20; - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP - //////////////////////////////////////////////////////////////////////////*/ - - /// @inheritdoc ISablierV2ProxyTarget - function batchCancelMultiple( - Batch.CancelMultiple[] calldata batch, - IERC20[] calldata assets - ) - external - onlyDelegateCall - { - // Check that the batch size is not zero. - uint256 batchSize = batch.length; - if (batchSize == 0) { - revert Errors.SablierV2ProxyTarget_BatchSizeZero(); - } - - // Load the balances before the cancellations. - uint256[] memory initialBalances = _getBalances(assets); - - for (uint256 i = 0; i < batchSize;) { - // Cancel the streams. - batch[i].lockup.cancelMultiple(batch[i].streamIds); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - - // Transfer the balance differences to the proxy owner. - _postMultipleCancellations(initialBalances, assets); - } - - /// @inheritdoc ISablierV2ProxyTarget - function burn(ISablierV2Lockup lockup, uint256 streamId) external onlyDelegateCall { - lockup.burn(streamId); - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancel(ISablierV2Lockup lockup, uint256 streamId) public onlyDelegateCall { - // Retrieve the asset used for streaming. - IERC20 asset = lockup.getAsset(streamId); - - // Load the balance before the cancellation. - uint256 initialBalance = asset.balanceOf(address(this)); - - // Cancel the stream. - lockup.cancel(streamId); - - // Calculate the difference between the final and the initial balance. - uint256 finalBalance = asset.balanceOf(address(this)); - uint256 deltaBalance = finalBalance - initialBalance; - - // Forward the delta to the proxy owner. This cannot be zero because settled streams cannot be canceled. - asset.safeTransfer({ to: _getOwner(), value: deltaBalance }); - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancelMultiple( - ISablierV2Lockup lockup, - IERC20[] calldata assets, - uint256[] calldata streamIds - ) - external - onlyDelegateCall - { - // Load the balances before the cancellations. - uint256[] memory initialBalances = _getBalances(assets); - - // Cancel the streams. - lockup.cancelMultiple(streamIds); - - // Transfer the balance differences to the proxy owner. - _postMultipleCancellations(initialBalances, assets); - } - - /// @inheritdoc ISablierV2ProxyTarget - function renounce(ISablierV2Lockup lockup, uint256 streamId) external onlyDelegateCall { - lockup.renounce(streamId); - } - - /// @inheritdoc ISablierV2ProxyTarget - function withdraw( - ISablierV2Lockup lockup, - uint256 streamId, - address to, - uint128 amount - ) - external - onlyDelegateCall - { - lockup.withdraw(streamId, to, amount); - } - - /// @inheritdoc ISablierV2ProxyTarget - function withdrawMax(ISablierV2Lockup lockup, uint256 streamId, address to) external onlyDelegateCall { - lockup.withdrawMax(streamId, to); - } - - /// @inheritdoc ISablierV2ProxyTarget - function withdrawMaxAndTransfer( - ISablierV2Lockup lockup, - uint256 streamId, - address newRecipient - ) - external - onlyDelegateCall - { - lockup.withdrawMaxAndTransfer(streamId, newRecipient); - } - - /// @inheritdoc ISablierV2ProxyTarget - function withdrawMultiple( - ISablierV2Lockup lockup, - uint256[] calldata streamIds, - address to, - uint128[] calldata amounts - ) - external - onlyDelegateCall - { - lockup.withdrawMultiple(streamIds, to, amounts); - } - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP-LINEAR - //////////////////////////////////////////////////////////////////////////*/ - - /// @inheritdoc ISablierV2ProxyTarget - function batchCreateWithDurations( - ISablierV2LockupLinear lockupLinear, - IERC20 asset, - Batch.CreateWithDurations[] calldata batch, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256[] memory streamIds) - { - // Check that the batch size is not zero. - uint256 batchSize = batch.length; - if (batchSize == 0) { - revert Errors.SablierV2ProxyTarget_BatchSizeZero(); - } - - // Calculate the sum of all of stream amounts. It is safe to use unchecked addition because one of the create - // transactions will revert if there is overflow. - uint256 i; - uint160 transferAmount; - for (i = 0; i < batchSize;) { - unchecked { - transferAmount += batch[i].totalAmount; - i += 1; - } - } - - // Transfers the assets to the proxy and approves the Sablier contract to spend them. - _handleTransfer(address(lockupLinear), asset, transferAmount, transferData); - - // Create a stream for each element in the parameter array. - streamIds = new uint256[](batchSize); - for (i = 0; i < batchSize;) { - // Create the stream. - streamIds[i] = lockupLinear.createWithDurations( - LockupLinear.CreateWithDurations({ - asset: asset, - broker: batch[i].broker, - cancelable: batch[i].cancelable, - durations: batch[i].durations, - recipient: batch[i].recipient, - sender: batch[i].sender, - totalAmount: batch[i].totalAmount, - transferable: batch[i].transferable - }) - ); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - } - - /// @inheritdoc ISablierV2ProxyTarget - function batchCreateWithRange( - ISablierV2LockupLinear lockupLinear, - IERC20 asset, - Batch.CreateWithRange[] calldata batch, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256[] memory streamIds) - { - // Check that the batch is not empty. - uint256 batchSize = batch.length; - if (batchSize == 0) { - revert Errors.SablierV2ProxyTarget_BatchSizeZero(); - } - - // Calculate the sum of all of stream amounts. It is safe to use unchecked addition because one of the create - // transactions will revert if there is overflow. - uint256 i; - uint160 transferAmount; - for (i = 0; i < batchSize;) { - unchecked { - transferAmount += batch[i].totalAmount; - i += 1; - } - } - - // Transfers the assets to the proxy and approve the Sablier contract to spend them. - _handleTransfer(address(lockupLinear), asset, transferAmount, transferData); - - // Create a stream for each element in the parameter array. - streamIds = new uint256[](batchSize); - for (i = 0; i < batchSize;) { - // Create the stream. - streamIds[i] = lockupLinear.createWithRange( - LockupLinear.CreateWithRange({ - asset: asset, - broker: batch[i].broker, - cancelable: batch[i].cancelable, - range: batch[i].range, - recipient: batch[i].recipient, - sender: batch[i].sender, - totalAmount: batch[i].totalAmount, - transferable: batch[i].transferable - }) - ); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancelAndCreateWithDurations( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations calldata createParams, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256 newStreamId) - { - cancel(lockup, streamId); - newStreamId = createWithDurations(lockupLinear, createParams, transferData); - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancelAndCreateWithRange( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange calldata createParams, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256 newStreamId) - { - cancel(lockup, streamId); - newStreamId = createWithRange(lockupLinear, createParams, transferData); - } - - /// @inheritdoc ISablierV2ProxyTarget - function createWithDurations( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations calldata createParams, - bytes calldata transferData - ) - public - override - onlyDelegateCall - returns (uint256 streamId) - { - _handleTransfer(address(lockupLinear), createParams.asset, createParams.totalAmount, transferData); - streamId = lockupLinear.createWithDurations(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function createWithRange( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange calldata createParams, - bytes calldata transferData - ) - public - override - onlyDelegateCall - returns (uint256 streamId) - { - _handleTransfer(address(lockupLinear), createParams.asset, createParams.totalAmount, transferData); - streamId = lockupLinear.createWithRange(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function wrapAndCreateWithDurations( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations memory createParams - ) - external - payable - override - onlyDelegateCall - returns (uint256 streamId) - { - // All production chains have a native asset with a circulating supply much smaller than 2^128. - createParams.totalAmount = uint128(msg.value); - - // Safely wrap the native asset payment in ERC-20 form. - _safeWrap(createParams.asset); - - // Approve the Sablier contract to spend funds. - _approve(address(lockupLinear), createParams.asset, createParams.totalAmount); - - // Create the stream. - streamId = lockupLinear.createWithDurations(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function wrapAndCreateWithRange( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange memory createParams - ) - external - payable - override - onlyDelegateCall - returns (uint256 streamId) - { - // All production chains have a native asset with a circulating supply much smaller than 2^128. - createParams.totalAmount = uint128(msg.value); - - // Safely wrap the native asset payment in ERC-20 form. - _safeWrap(createParams.asset); - - // Approve the Sablier contract to spend funds. - _approve(address(lockupLinear), createParams.asset, createParams.totalAmount); - - // Create the stream. - streamId = lockupLinear.createWithRange(createParams); - } - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP-DYNAMIC - //////////////////////////////////////////////////////////////////////////*/ - - /// @inheritdoc ISablierV2ProxyTarget - function batchCreateWithDeltas( - ISablierV2LockupDynamic dynamic, - IERC20 asset, - Batch.CreateWithDeltas[] calldata batch, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256[] memory streamIds) - { - // Check that the batch size is not zero. - uint256 batchSize = batch.length; - if (batchSize == 0) { - revert Errors.SablierV2ProxyTarget_BatchSizeZero(); - } - - // Calculate the sum of all of stream amounts. It is safe to use unchecked addition because one of the create - // transactions will revert if there is overflow. - uint256 i; - uint160 transferAmount; - for (i = 0; i < batchSize;) { - unchecked { - transferAmount += batch[i].totalAmount; - i += 1; - } - } - - // Perform the ERC-20 transfer and approve {SablierV2LockupDynamic} to spend the amount of assets. - _handleTransfer(address(dynamic), asset, transferAmount, transferData); - - // Create a stream for each element in the parameter array. - streamIds = new uint256[](batchSize); - for (i = 0; i < batchSize;) { - // Create the stream. - streamIds[i] = dynamic.createWithDeltas( - LockupDynamic.CreateWithDeltas({ - asset: asset, - broker: batch[i].broker, - cancelable: batch[i].cancelable, - recipient: batch[i].recipient, - segments: batch[i].segments, - sender: batch[i].sender, - totalAmount: batch[i].totalAmount, - transferable: batch[i].transferable - }) - ); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - } - - /// @inheritdoc ISablierV2ProxyTarget - function batchCreateWithMilestones( - ISablierV2LockupDynamic dynamic, - IERC20 asset, - Batch.CreateWithMilestones[] calldata batch, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256[] memory streamIds) - { - // Check that the batch size is not zero. - uint256 batchSize = batch.length; - if (batchSize == 0) { - revert Errors.SablierV2ProxyTarget_BatchSizeZero(); - } - - // Calculate the sum of all of stream amounts. It is safe to use unchecked addition because one of the create - // transactions will revert if there is overflow. - uint256 i; - uint160 transferAmount; - for (i = 0; i < batchSize;) { - unchecked { - transferAmount += batch[i].totalAmount; - i += 1; - } - } - - // Perform the ERC-20 transfer and approve {SablierV2LockupDynamic} to spend the amount of assets. - _handleTransfer(address(dynamic), asset, transferAmount, transferData); - - // Create a stream for each element in the parameter array. - streamIds = new uint256[](batchSize); - for (i = 0; i < batchSize;) { - // Create the stream. - streamIds[i] = dynamic.createWithMilestones( - LockupDynamic.CreateWithMilestones({ - asset: asset, - broker: batch[i].broker, - cancelable: batch[i].cancelable, - recipient: batch[i].recipient, - segments: batch[i].segments, - sender: batch[i].sender, - startTime: batch[i].startTime, - totalAmount: batch[i].totalAmount, - transferable: batch[i].transferable - }) - ); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancelAndCreateWithDeltas( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithDeltas calldata createParams, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256 newStreamId) - { - cancel(lockup, streamId); - newStreamId = createWithDeltas(dynamic, createParams, transferData); - } - - /// @inheritdoc ISablierV2ProxyTarget - function cancelAndCreateWithMilestones( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithMilestones calldata createParams, - bytes calldata transferData - ) - external - override - onlyDelegateCall - returns (uint256 newStreamId) - { - cancel(lockup, streamId); - newStreamId = createWithMilestones(dynamic, createParams, transferData); - } - - /// @inheritdoc ISablierV2ProxyTarget - function createWithDeltas( - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithDeltas calldata createParams, - bytes calldata transferData - ) - public - override - onlyDelegateCall - returns (uint256 streamId) - { - _handleTransfer(address(dynamic), createParams.asset, createParams.totalAmount, transferData); - streamId = dynamic.createWithDeltas(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function createWithMilestones( - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithMilestones calldata createParams, - bytes calldata transferData - ) - public - override - onlyDelegateCall - returns (uint256 streamId) - { - _handleTransfer(address(dynamic), createParams.asset, createParams.totalAmount, transferData); - streamId = dynamic.createWithMilestones(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function wrapAndCreateWithDeltas( - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithDeltas memory createParams - ) - external - payable - override - onlyDelegateCall - returns (uint256 streamId) - { - // All production chains have a native asset with a circulating supply much smaller than 2^128. - createParams.totalAmount = uint128(msg.value); - - // Safely wrap the native asset payment in ERC-20 form. - _safeWrap(createParams.asset); - - // Approve the Sablier contract to spend funds. - _approve(address(dynamic), createParams.asset, createParams.totalAmount); - - // Create the stream. - streamId = dynamic.createWithDeltas(createParams); - } - - /// @inheritdoc ISablierV2ProxyTarget - function wrapAndCreateWithMilestones( - ISablierV2LockupDynamic dynamic, - LockupDynamic.CreateWithMilestones memory createParams - ) - external - payable - override - onlyDelegateCall - returns (uint256 streamId) - { - // All production chains have a native asset with a circulating supply much smaller than 2^128. - createParams.totalAmount = uint128(msg.value); - - // Safely wrap the native asset payment in ERC-20 form. - _safeWrap(createParams.asset); - - // Approve the Sablier contract to spend funds. - _approve(address(dynamic), createParams.asset, createParams.totalAmount); - - // Create the stream. - streamId = dynamic.createWithMilestones(createParams); - } - - /*////////////////////////////////////////////////////////////////////////// - HELPER FUNCTIONS - //////////////////////////////////////////////////////////////////////////*/ - - /// @dev Helper function to approve a Sablier contract to spend funds from the proxy. If the current allowance - /// is insufficient, this function approves Sablier to spend the exact `amount`. - /// The {SafeERC20.forceApprove} function is used to handle special ERC-20 assets (e.g. USDT) that require the - /// current allowance to be zero before setting it to a non-zero value. - function _approve(address sablierContract, IERC20 asset, uint256 amount) internal { - uint256 allowance = asset.allowance({ owner: address(this), spender: sablierContract }); - if (allowance < amount) { - asset.forceApprove({ spender: sablierContract, value: amount }); - } - } - - /// @dev Helper function to retrieve the proxy's balance for the provided assets. - function _getBalances(IERC20[] calldata assets) internal view returns (uint256[] memory initialBalances) { - uint256 assetCount = assets.length; - initialBalances = new uint256[](assetCount); - for (uint256 i = 0; i < assetCount;) { - initialBalances[i] = assets[i].balanceOf(address(this)); - unchecked { - i += 1; - } - } - } - - /// @dev Helper function to retrieve the proxy's owner, which is stored as an immutable variable in the proxy. - function _getOwner() internal view returns (address) { - return IPRBProxy(address(this)).owner(); - } - - /// @dev Handler function meant to be inherited by child contracts that implement the transfer logic. This function - /// may also approve the Sablier contract to spend to spend funds from the proxy if the allowance is insufficient. - function _handleTransfer( - address sablierContract, - IERC20 asset, - uint160 amount, - bytes calldata transferData - ) - internal - virtual; - - /// @dev Shared logic between {cancelMultiple} and {batchCancelMultiple}. - function _postMultipleCancellations(uint256[] memory initialBalances, IERC20[] calldata assets) internal { - uint256 assetCount = assets.length; - uint256 finalBalance; - uint256 deltaBalance; - for (uint256 i = 0; i < assetCount;) { - // Calculate the difference between the final and initial balances. - finalBalance = assets[i].balanceOf(address(this)); - deltaBalance = finalBalance - initialBalances[i]; - - // Forward the delta to the proxy owner. This cannot be zero because settled streams cannot be canceled. - assets[i].safeTransfer({ to: _getOwner(), value: deltaBalance }); - - // Increment the for loop iterator. - unchecked { - i += 1; - } - } - } - - /// @dev Safely wraps the native asset payment in ERC-20 form, checking that the credit amount is greater than or - /// equal to `msg.value`. - function _safeWrap(IERC20 asset) internal { - // Load the balance before the wrap. - uint256 initialBalance = asset.balanceOf(address(this)); - - // Wrap the native asset payment in ERC-20 form. - IWrappedNativeAsset(address(asset)).deposit{ value: msg.value }(); - - // Calculate the credit amount. - uint256 finalBalance = asset.balanceOf(address(this)); - uint256 creditAmount = finalBalance - initialBalance; - - // Check that the credit amount is equal to `msg.value`. - if (creditAmount != msg.value) { - revert Errors.SablierV2ProxyTarget_CreditAmountMismatch({ msgValue: msg.value, creditAmount: creditAmount }); - } - } -} diff --git a/src/interfaces/ISablierV2ProxyTarget.sol b/src/interfaces/ISablierV2ProxyTarget.sol deleted file mode 100644 index 54a2420f..00000000 --- a/src/interfaces/ISablierV2ProxyTarget.sol +++ /dev/null @@ -1,437 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { ISablierV2LockupLinear } from "@sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol"; -import { ISablierV2LockupDynamic } from "@sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Batch } from "../types/DataTypes.sol"; - -/// @title ISablierV2ProxyTarget -/// @notice Proxy target with stateless scripts for interacting with Sablier V2, designed to be used by -/// stream senders. -/// @dev Intended for use with an instance of PRBProxy through delegate calls. Any standard calls will be reverted. -interface ISablierV2ProxyTarget { - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Cancels multiple streams across different lockup contracts. - /// - /// @dev Notes: - /// - All refunded assets are forwarded to the proxy owner. - /// - It is assumed that `assets` includes only the assets associated with the stream ids in `batch`. If any asset - /// is missing, the refunded amount will be left in the proxy. - /// - /// Requirements: - /// - Must be delegate called. - /// - There must be at least one element in `batch`. - /// - /// @param batch An array of structs, each encapsulating the lockup contract's address and the stream id to cancel. - /// @param assets The contract addresses of the ERC-20 assets used for streaming. - function batchCancelMultiple(Batch.CancelMultiple[] calldata batch, IERC20[] calldata assets) external; - - /// @notice Mirror for {ISablierV2Lockup.burn}. - /// @dev Must be delegate called. - function burn(ISablierV2Lockup lockup, uint256 streamId) external; - - /// @notice Mirror for {ISablierV2Lockup.cancel}. - /// - /// @dev Notes: - /// - All refunded assets are forwarded to the proxy owner. - /// - /// Requirements: - /// - Must be delegate called. - function cancel(ISablierV2Lockup lockup, uint256 streamId) external; - - /// @notice Mirror for {ISablierV2Lockup.cancelMultiple}. - /// - /// @dev Notes: - /// - All refunded assets are forwarded to the proxy owner. - /// - It is assumed that `assets` includes only the assets associated with `streamIds`. If any asset is missing, the - /// refunded amount will be left in the proxy. - /// - /// Requirements: - /// - Must be delegate called. - /// - /// @param lockup The address of the Lockup streaming contract. - /// @param assets The contract addresses of the ERC-20 assets used for streaming. - /// @param streamIds The stream ids to cancel. - function cancelMultiple(ISablierV2Lockup lockup, IERC20[] calldata assets, uint256[] calldata streamIds) external; - - /// @notice Mirror for {ISablierV2Lockup.renounce}. - /// @dev Must be delegate called. - function renounce(ISablierV2Lockup lockup, uint256 streamId) external; - - /// @notice Mirror for {ISablierV2Lockup.withdraw}. - /// @dev Must be delegate called. - function withdraw(ISablierV2Lockup lockup, uint256 streamId, address to, uint128 amount) external; - - /// @notice Mirror for {ISablierV2Lockup.withdrawMax}. - /// @dev Must be delegate called. - function withdrawMax(ISablierV2Lockup lockup, uint256 streamId, address to) external; - - /// @notice Mirror for {ISablierV2Lockup.withdrawMaxAndTransfer}. - /// @dev Must be delegate called. - function withdrawMaxAndTransfer(ISablierV2Lockup lockup, uint256 streamId, address newRecipient) external; - - /// @notice Mirror for {ISablierV2Lockup.withdrawMultiple}. - /// @dev Must be delegate called. - function withdrawMultiple( - ISablierV2Lockup lockup, - uint256[] calldata streamIds, - address to, - uint128[] calldata amounts - ) - external; - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP-LINEAR - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Creates a batch of Lockup Linear streams using `createWithDurations`. - /// - /// @dev Requirements: - /// - Must be delegate called. - /// - There must be at least one element in `batch`. - /// - All requirements from {ISablierV2LockupLinear.createWithDurations} must be met for each stream. - /// - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param asset The contract address of the ERC-20 asset used for streaming. - /// @param batch An array of structs, each encapsulating a subset of the parameters of - /// {SablierV2LockupLinear.createWithDurations}. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamIds The ids of the newly created streams. - function batchCreateWithDurations( - ISablierV2LockupLinear lockupLinear, - IERC20 asset, - Batch.CreateWithDurations[] calldata batch, - bytes calldata transferData - ) - external - returns (uint256[] memory streamIds); - - /// @notice Creates a batch of Lockup Linear streams using `createWithRange`. - /// - /// @dev Requirements: - /// - Must be delegate called. - /// - There must be at least one element in `batch`. - /// - All requirements from {ISablierV2LockupLinear.createWithRange} must be met for each stream. - /// - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param asset The contract address of the ERC-20 asset used for streaming. - /// @param batch An array of structs, each encapsulating a subset of the parameters of - /// {SablierV2LockupLinear.createWithRange}. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamIds The ids of the newly created streams. - function batchCreateWithRange( - ISablierV2LockupLinear lockupLinear, - IERC20 asset, - Batch.CreateWithRange[] calldata batch, - bytes calldata transferData - ) - external - returns (uint256[] memory streamIds); - - /// @notice Cancels a Lockup stream and creates a new Lockup Linear stream using `createWithDurations`. - /// - /// @dev Notes: - /// - `streamId` can reference either a Lockup Linear or a Lockup Dynamic stream. - /// - See {ISablierV2Lockup.cancel} and {ISablierV2LockupLinear.createWithDurations} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - /// @param lockup The address of the Lockup streaming contract where the stream to cancel is. - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract to use for creating the new stream. - /// @param streamId The id of the stream to cancel. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return newStreamId The id of the newly created stream. - function cancelAndCreateWithDurations( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 newStreamId); - - /// @notice Cancels a Lockup stream and creates a new Lockup Linear stream using `createWithRange`. - /// - /// @dev Notes: - /// - `streamId` can reference either a Lockup Linear or a Lockup Dynamic stream. - /// - See {ISablierV2Lockup.cancel} and {ISablierV2LockupLinear.createWithRange} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - /// @param lockup The address of the Lockup streaming contract where the stream to cancel is. - /// @param streamId The id of the stream to cancel. - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract to use for creating the new stream. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return newStreamId The id of the newly created stream. - function cancelAndCreateWithRange( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 newStreamId); - - /// @notice Mirror for {SablierV2LockupLinear.createWithDurations}. - /// @dev Must be delegate called. - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamId The id of the newly created stream. - function createWithDurations( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 streamId); - - /// @notice Mirror for {SablierV2LockupLinear.createWithRange}. - /// @dev Must be delegate called. - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamId The id of the newly created stream. - function createWithRange( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 streamId); - - /// @notice Wraps the native asset payment in ERC-20 form and creates a Lockup Linear stream using - /// `createWithDurations`. - /// - /// @dev Notes: - /// - `createParams.totalAmount` is overwritten with `msg.value`. - /// - See {ISablierV2LockupLinear.createWithDurations} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - The ERC-20 amount credited by the wrapper contract must be equal to `msg.value`. - /// - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - function wrapAndCreateWithDurations( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithDurations memory createParams - ) - external - payable - returns (uint256 streamId); - - /// @notice Wraps the native asset payment in ERC-20 form and creates a Lockup Linear stream using - /// `createWithRange`. - /// - /// @dev Notes: - /// - `createParams.totalAmount` is overwritten with `msg.value`. - /// - See {ISablierV2LockupLinear.createWithRange} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - The ERC-20 amount credited by the wrapper contract must be equal to `msg.value`. - /// - /// @param lockupLinear The address of the {SablierV2LockupLinear} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - function wrapAndCreateWithRange( - ISablierV2LockupLinear lockupLinear, - LockupLinear.CreateWithRange memory createParams - ) - external - payable - returns (uint256 streamId); - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-LOCKUP-DYNAMIC - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Creates a batch of Lockup Dynamic streams using `createWithDeltas`. - /// - /// @dev Requirements: - /// - Must be delegate called. - /// - There must be at least one element in `batch`. - /// - All requirements from {ISablierV2LockupDynamic.createWithDeltas} must be met for each stream. - /// - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param asset The contract address of the ERC-20 asset used for streaming. - /// @param batch An array of structs, each encapsulating a subset of the parameters of - /// {SablierV2LockupDynamic.createWithDeltas}. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamIds The ids of the newly created streams. - function batchCreateWithDeltas( - ISablierV2LockupDynamic lockupDynamic, - IERC20 asset, - Batch.CreateWithDeltas[] calldata batch, - bytes calldata transferData - ) - external - returns (uint256[] memory streamIds); - - /// @notice Creates a batch of Lockup Dynamic streams using `createWithMilestones`. - /// - /// @dev Requirements: - /// - Must be delegate called. - /// - There must be at least one element in `batch`. - /// - All requirements from {ISablierV2LockupDynamic.createWithMilestones} must be met for each stream. - /// - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param asset The contract address of the ERC-20 asset used for streaming. - /// @param batch An array of structs, each encapsulating a subset of the parameters of - /// {SablierV2LockupDynamic.createWithMilestones}. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamIds The ids of the newly created streams. - function batchCreateWithMilestones( - ISablierV2LockupDynamic lockupDynamic, - IERC20 asset, - Batch.CreateWithMilestones[] calldata batch, - bytes calldata transferData - ) - external - returns (uint256[] memory streamIds); - - /// @notice Cancels a Lockup stream and creates a new Lockup Dynamic stream using `createWithDeltas`. - /// - /// @dev Notes: - /// - `streamId` can reference either a Lockup Linear or a Lockup Dynamic stream. - /// - See {ISablierV2Lockup.cancel} and {ISablierV2LockupDynamic.createWithDeltas} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - /// @param lockup The address of the Lockup streaming contract where the stream to cancel is. - /// @param streamId The id of the stream to cancel. - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract to use for creating the new stream. - /// @param createParams A struct encapsulating the create function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return newStreamId The id of the newly created stream. - function cancelAndCreateWithDeltas( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithDeltas calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 newStreamId); - - /// @notice Cancels a Lockup stream and creates a new Lockup Dynamic stream using `createWithMilestones`. - /// - /// @dev Notes: - /// - `streamId` can reference either a Lockup Linear or a Lockup Dynamic stream. - /// - See {ISablierV2Lockup.cancel} and {ISablierV2LockupDynamic.createWithMilestones} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - /// @param lockup The address of the Lockup streaming contract where the stream to cancel is. - /// @param streamId The id of the stream to cancel. - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract to use for creating the new stream. - /// @param createParams A struct encapsulating the create function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return newStreamId The id of the newly created stream. - function cancelAndCreateWithMilestones( - ISablierV2Lockup lockup, - uint256 streamId, - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithMilestones calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 newStreamId); - - /// @notice Mirror for {SablierV2LockupDynamic.createWithDeltas}. - /// @dev Must be delegate called. - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param createParams A struct encapsulating the create function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamId The id of the newly created stream. - function createWithDeltas( - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithDeltas calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 streamId); - - /// @notice Mirror for {SablierV2LockupDynamic.createWithMilestones}. - /// @dev Must be delegate called. - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - /// @param transferData Bytes used for additional information, specific to the implementation, it may contain the - /// parameters needed for Permit2 in one implementation and may be ignored in another. - /// @return streamId The id of the newly created stream. - function createWithMilestones( - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithMilestones calldata createParams, - bytes calldata transferData - ) - external - returns (uint256 streamId); - - /// @notice Wraps the native asset payment in ERC-20 form and creates a Lockup Dynamic stream using - /// `createWithDeltas`. - /// - /// @dev Notes: - /// - `createParams.totalAmount` is overwritten with `msg.value`. - /// - See {ISablierV2LockupDynamic.createWithDeltas} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - The ERC-20 amount credited by the wrapper contract must be equal to `msg.value`. - /// - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - /// @return streamId The id of the newly created stream. - function wrapAndCreateWithDeltas( - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithDeltas memory createParams - ) - external - payable - returns (uint256 streamId); - - /// @notice Wraps the native asset payment in ERC-20 form and creates a Lockup Dynamic stream using - /// `createWithMilestones`. - /// - /// @dev Notes: - /// - `createParams.totalAmount` is overwritten with `msg.value`. - /// - See {ISablierV2LockupDynamic.createWithMilestones} for full documentation. - /// - /// Requirements: - /// - Must be delegate called. - /// - The ERC-20 amount credited by the wrapper contract must be equal to `msg.value`. - /// - /// @param lockupDynamic The address of the {SablierV2LockupDynamic} contract. - /// @param createParams Struct encapsulating the function parameters, which are documented in V2 Core. - /// @return streamId The id of the newly created stream. - function wrapAndCreateWithMilestones( - ISablierV2LockupDynamic lockupDynamic, - LockupDynamic.CreateWithMilestones memory createParams - ) - external - payable - returns (uint256 streamId); -} diff --git a/src/interfaces/IWrappedNativeAsset.sol b/src/interfaces/IWrappedNativeAsset.sol deleted file mode 100644 index 16b60ad0..00000000 --- a/src/interfaces/IWrappedNativeAsset.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -/// @title IWrappedNativeAsset -/// @notice An interface for contracts that wrap native assets in ERC-20 form, such as WETH. -/// @dev A generic name is used instead of "WETH" to accommodate chains with different native assets. -interface IWrappedNativeAsset is IERC20 { - /// @notice Deposits native assets to receive ERC-20 wrapped assets. - function deposit() external payable; - - /// @notice Withdraws ERC-20 wrapped assets to obtain native assets. - /// @param amount The amount of ERC-20 wrapped assets to withdraw. - function withdraw(uint256 amount) external; -} diff --git a/src/libraries/Errors.sol b/src/libraries/Errors.sol index eb896880..93308ed9 100644 --- a/src/libraries/Errors.sol +++ b/src/libraries/Errors.sol @@ -4,13 +4,6 @@ pragma solidity >=0.8.19; /// @title Errors /// @notice Library containing all custom errors the protocol may revert with. library Errors { - /*////////////////////////////////////////////////////////////////////////// - GENERICS - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Thrown when trying to perform a standard call to a function that allows only delegate calls. - error CallNotDelegateCall(); - /*////////////////////////////////////////////////////////////////////////// SABLIER-V2-BATCH //////////////////////////////////////////////////////////////////////////*/ @@ -35,14 +28,4 @@ library Errors { /// @notice Thrown when trying to claim the same stream more than once. error SablierV2MerkleStreamer_StreamClaimed(uint256 index); - - /*////////////////////////////////////////////////////////////////////////// - SABLIER-V2-PROXY-TARGET - //////////////////////////////////////////////////////////////////////////*/ - - /// @notice Thrown when trying to perform an action that requires the batch size to not be zero. - error SablierV2ProxyTarget_BatchSizeZero(); - - /// @notice Thrown when trying to wrap and create a stream and the credit amount is not equal to `msg.value`. - error SablierV2ProxyTarget_CreditAmountMismatch(uint256 msgValue, uint256 creditAmount); } diff --git a/src/types/Permit2.sol b/src/types/Permit2.sol deleted file mode 100644 index 175ed89a..00000000 --- a/src/types/Permit2.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// solhint-disable no-unused-import -pragma solidity >=0.8.19; - -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; -import { IPermit2 } from "@uniswap/permit2/interfaces/IPermit2.sol"; // unused but re-exported for convenience - -/// @notice A struct encapsulating the parameters needed for Permit2. -/// @dev See the full documentation at https://github.com/Uniswap/permit2. -/// @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.PermitSingle permitSingle; - bytes signature; -} diff --git a/src/types/Proxy.sol b/src/types/Proxy.sol deleted file mode 100644 index cea59fcb..00000000 --- a/src/types/Proxy.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// solhint-disable no-unused-import -pragma solidity >=0.8.19; - -// Proxy.sol -// -// This file re-exports all PRBProxy interfaces used in V2 Periphery. It is provided for convenience so -// that users don't have to install PRBProxy separately. - -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; -import { IPRBProxyRegistry } from "@prb/proxy/src/interfaces/IPRBProxyRegistry.sol"; diff --git a/test/Base.t.sol b/test/Base.t.sol index aba90b93..8f08944d 100644 --- a/test/Base.t.sol +++ b/test/Base.t.sol @@ -5,14 +5,10 @@ pragma solidity >=0.8.19 <0.9.0; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; -import { IPRBProxyRegistry } from "@prb/proxy/src/interfaces/IPRBProxyRegistry.sol"; import { ISablierV2Comptroller } from "@sablier/v2-core/src/interfaces/ISablierV2Comptroller.sol"; -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; import { ISablierV2LockupDynamic } from "@sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol"; import { ISablierV2LockupLinear } from "@sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol"; import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { Assertions as V2CoreAssertions } from "@sablier/v2-core-test/utils/Assertions.sol"; import { Utils as V2CoreUtils } from "@sablier/v2-core-test/utils/Utils.sol"; @@ -20,16 +16,10 @@ import { Utils as V2CoreUtils } from "@sablier/v2-core-test/utils/Utils.sol"; import { ISablierV2Batch } from "src/interfaces/ISablierV2Batch.sol"; import { ISablierV2MerkleStreamerFactory } from "src/interfaces/ISablierV2MerkleStreamerFactory.sol"; import { ISablierV2MerkleStreamerLL } from "src/interfaces/ISablierV2MerkleStreamerLL.sol"; -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; -import { IWrappedNativeAsset } from "src/interfaces/IWrappedNativeAsset.sol"; import { SablierV2Batch } from "src/SablierV2Batch.sol"; import { SablierV2MerkleStreamerFactory } from "src/SablierV2MerkleStreamerFactory.sol"; import { SablierV2MerkleStreamerLL } from "src/SablierV2MerkleStreamerLL.sol"; -import { SablierV2ProxyTargetApprove } from "src/SablierV2ProxyTargetApprove.sol"; -import { SablierV2ProxyTargetPermit2 } from "src/SablierV2ProxyTargetPermit2.sol"; -import { SablierV2ProxyTargetPush } from "src/SablierV2ProxyTargetPush.sol"; -import { WLC } from "./mocks/WLC.sol"; import { Defaults } from "./utils/Defaults.sol"; import { DeployOptimized } from "./utils/DeployOptimized.sol"; import { Events } from "./utils/Events.sol"; @@ -48,7 +38,6 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions TEST CONTRACTS //////////////////////////////////////////////////////////////////////////*/ - IPRBProxy internal aliceProxy; IERC20 internal asset; ISablierV2Batch internal batch; ISablierV2Comptroller internal comptroller; @@ -57,14 +46,6 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions ISablierV2LockupLinear internal lockupLinear; ISablierV2MerkleStreamerFactory internal merkleStreamerFactory; ISablierV2MerkleStreamerLL internal merkleStreamerLL; - IAllowanceTransfer internal permit2; - IPRBProxyRegistry internal proxyRegistry; - ISablierV2ProxyTarget internal target; - SablierV2ProxyTargetApprove internal targetApprove; - SablierV2ProxyTargetPermit2 internal targetPermit2; - SablierV2ProxyTargetPush internal targetPush; - IWrappedNativeAsset internal weth; - WLC internal wlc; /*////////////////////////////////////////////////////////////////////////// SET-UP FUNCTION @@ -92,22 +73,17 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions /// @dev Approves relevant contracts to spend assets from some users. function approveContracts() internal { - // Approve Permit2 to spend assets from the stream's recipient. - vm.startPrank({ msgSender: users.recipient0.addr }); - asset.approve({ spender: address(permit2), amount: MAX_UINT256 }); - - // Approve Permit2, Batch and Alice's Proxy to spend assets from Alice (the proxy owner). - changePrank({ msgSender: users.alice.addr }); + // Approve Batch to spend assets from Alice. + changePrank({ msgSender: users.alice }); asset.approve({ spender: address(batch), amount: MAX_UINT256 }); - asset.approve({ spender: address(permit2), amount: MAX_UINT256 }); - asset.approve({ spender: address(aliceProxy), amount: MAX_UINT256 }); } /// @dev Generates a user, labels its address, and funds it with ETH. - function createUser(string memory name) internal returns (Account memory user) { - user = makeAccount(name); - vm.deal({ account: user.addr, newBalance: 100_000 ether }); - deal({ token: address(asset), to: user.addr, give: 1_000_000e18 }); + function createUser(string memory name) internal returns (address payable) { + address user = makeAddr(name); + vm.deal({ account: user, newBalance: 100_000 ether }); + deal({ token: address(asset), to: user, give: 1_000_000e18 }); + return payable(user); } /// @dev Conditionally deploy V2 Periphery normally or from an optimized source compiled with `--via-ir`. @@ -115,19 +91,13 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions if (!isTestOptimizedProfile()) { batch = new SablierV2Batch(); merkleStreamerFactory = new SablierV2MerkleStreamerFactory(); - targetApprove = new SablierV2ProxyTargetApprove(); - targetPermit2 = new SablierV2ProxyTargetPermit2(permit2); - targetPush = new SablierV2ProxyTargetPush(); } else { - (batch, merkleStreamerFactory, targetApprove, targetPermit2, targetPush) = deployOptimizedPeriphery(permit2); + (batch, merkleStreamerFactory) = deployOptimizedPeriphery(); } - // The default target. - target = targetApprove; } /// @dev Labels the most relevant contracts. function labelContracts() internal { - vm.label({ account: address(aliceProxy), newLabel: "Alice's Proxy" }); vm.label({ account: address(asset), newLabel: IERC20Metadata(address(asset)).symbol() }); vm.label({ account: address(merkleStreamerFactory), newLabel: "MerkleStreamerFactory" }); vm.label({ account: address(merkleStreamerLL), newLabel: "MerkleStreamerLL" }); @@ -135,56 +105,12 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions vm.label({ account: address(comptroller), newLabel: "Comptroller" }); vm.label({ account: address(lockupDynamic), newLabel: "LockupDynamic" }); vm.label({ account: address(lockupLinear), newLabel: "LockupLinear" }); - vm.label({ account: address(permit2), newLabel: "Permit2" }); - vm.label({ account: address(targetApprove), newLabel: "ProxyTargetApprove" }); - vm.label({ account: address(targetPermit2), newLabel: "ProxyTargetPermit2" }); - vm.label({ account: address(targetPush), newLabel: "ProxyTargetPush" }); - vm.label({ account: address(wlc), newLabel: "WLC" }); } /*////////////////////////////////////////////////////////////////////////// CALL EXPECTS //////////////////////////////////////////////////////////////////////////*/ - /// @dev Expects a call to {ISablierV2Lockup.cancel}. - function expectCallToCancel(ISablierV2Lockup lockup, uint256 streamId) internal { - vm.expectCall({ callee: address(lockup), data: abi.encodeCall(ISablierV2Lockup.cancel, (streamId)) }); - } - - /// @dev Expect calls to {ISablierV2Lockup.cancel}, {IERC20.transfer}, and {IERC20.transferFrom}. - function expectCallsToCancelAndTransfer( - ISablierV2Lockup cancelContract, - ISablierV2Lockup createContract, - uint256 streamId - ) - internal - { - expectCallToCancel(cancelContract, streamId); - - // Asset flow: Sablier → proxy → proxy owner - // Expect transfers from Sablier to the proxy, and then from the proxy to the proxy owner. - expectCallToTransfer({ to: address(aliceProxy), amount: defaults.PER_STREAM_AMOUNT() }); - expectCallToTransfer({ to: users.alice.addr, amount: defaults.PER_STREAM_AMOUNT() }); - - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - expectCallToTransferFrom({ - from: users.alice.addr, - to: address(aliceProxy), - amount: defaults.PER_STREAM_AMOUNT() - }); - expectCallToTransferFrom({ - from: address(aliceProxy), - to: address(createContract), - amount: defaults.PER_STREAM_AMOUNT() - }); - } - - /// @dev Expects a call to {ISablierV2Lockup.cancelMultiple}. - function expectCallToCancelMultiple(ISablierV2Lockup lockup, uint256[] memory streamIds) internal { - vm.expectCall({ callee: address(lockup), data: abi.encodeCall(ISablierV2Lockup.cancelMultiple, (streamIds)) }); - } - /// @dev Expects a call to {ISablierV2LockupDynamic.createWithDeltas}. function expectCallToCreateWithDeltas(LockupDynamic.CreateWithDeltas memory params) internal { vm.expectCall({ @@ -224,9 +150,7 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions /// @dev Expects a call to {IERC20.transfer}. function expectCallToTransfer(address asset_, address to, uint256 amount) internal { - if (target != targetPush) { - vm.expectCall({ callee: asset_, data: abi.encodeCall(IERC20.transfer, (to, amount)) }); - } + vm.expectCall({ callee: asset_, data: abi.encodeCall(IERC20.transfer, (to, amount)) }); } /// @dev Expects a call to {IERC20.transferFrom}. @@ -236,9 +160,7 @@ abstract contract Base_Test is DeployOptimized, Events, Merkle, V2CoreAssertions /// @dev Expects a call to {IERC20.transferFrom}. function expectCallToTransferFrom(address asset_, address from, address to, uint256 amount) internal { - if (target != targetPush) { - vm.expectCall({ callee: asset_, data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) }); - } + vm.expectCall({ callee: asset_, data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) }); } /// @dev Expects multiple calls to {ISablierV2LockupDynamic.createWithDeltas}, each with the specified diff --git a/test/fork/Fork.t.sol b/test/fork/Fork.t.sol index e54cd83b..7d9dcced 100644 --- a/test/fork/Fork.t.sol +++ b/test/fork/Fork.t.sol @@ -2,28 +2,17 @@ pragma solidity >=0.8.19 <0.9.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; -import { IPRBProxyRegistry } from "@prb/proxy/src/interfaces/IPRBProxyRegistry.sol"; // import { ISablierV2LockupDynamic } from "@sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol"; // import { ISablierV2LockupLinear } from "@sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol"; import { Precompiles as V2CorePrecompiles } from "@sablier/v2-core-test/utils/Precompiles.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { Fuzzers as V2CoreFuzzers } from "@sablier/v2-core-test/utils/Fuzzers.sol"; -import { IWrappedNativeAsset } from "src/interfaces/IWrappedNativeAsset.sol"; import { Defaults } from "../utils/Defaults.sol"; import { Base_Test } from "../Base.t.sol"; /// @notice Common logic needed by all fork tests. abstract contract Fork_Test is Base_Test, V2CoreFuzzers { - /*////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////*/ - - /// @dev Goerli address of WETH. - address internal constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; - /*////////////////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////////*/ @@ -47,7 +36,7 @@ abstract contract Fork_Test is Base_Test, V2CoreFuzzers { loadDependencies(); // Deploy the defaults contract and allow it to access cheatcodes. - defaults = new Defaults(users, asset, permit2, aliceProxy); + defaults = new Defaults(users, asset); vm.allowCheatcodes(address(defaults)); // Deploy V2 Periphery. @@ -64,23 +53,6 @@ abstract contract Fork_Test is Base_Test, V2CoreFuzzers { HELPERS //////////////////////////////////////////////////////////////////////////*/ - /// @dev Approves the proxy or uses Permit2 to spend assets from the current pranked user. - function approveProxyOrPermit2(address proxy) internal { - if (target == targetApprove) { - asset.approve({ spender: proxy, amount: MAX_UINT256 }); - } else if (target == targetPermit2) { - maxApprovePermit2(); - } - } - - /// @dev Checks the user assumptions. - function checkUsers(address user, address recipient, address proxy_) internal virtual { - checkUsers(user, recipient); - - vm.assume(user != address(proxy_) && recipient != address(proxy_)); - assumeNoBlacklisted(address(asset), proxy_); - } - /// @dev Checks the user assumptions. function checkUsers(address user, address recipient) internal virtual { // The protocol does not allow the zero address to interact with it. @@ -98,26 +70,7 @@ abstract contract Fork_Test is Base_Test, V2CoreFuzzers { /// @dev Loads all dependencies pre-deployed on Mainnet. function loadDependencies() private { - weth = IWrappedNativeAsset(WETH_ADDRESS); - proxyRegistry = IPRBProxyRegistry(0x584009E9eDe26e212182c9745F5c000191296a78); - aliceProxy = loadOrDeployProxy(users.alice.addr); - permit2 = IAllowanceTransfer(0x000000000022D473030F116dDEE9F6B43aC78BA3); // TODO: update the contract addresses once they are deployed. - (, lockupDynamic, lockupLinear,) = new V2CorePrecompiles().deployCore(users.admin.addr); - } - - /// @dev Retrieves the proxy and deploys one if none is found. - function loadOrDeployProxy(address user) internal returns (IPRBProxy proxy) { - proxy = proxyRegistry.getProxy(user); - if (address(proxy) == address(0)) { - proxy = proxyRegistry.deployFor(user); - } - } - - /// @dev Approve Permit2 to spend assets from the current pranked user. We use a low-level call to ignore reverts - /// because the asset contract may have the missing return value bug. - function maxApprovePermit2() internal { - (bool success,) = address(asset).call(abi.encodeCall(IERC20.approve, (address(permit2), MAX_UINT256))); - success; + (, lockupDynamic, lockupLinear,) = new V2CorePrecompiles().deployCore(users.admin); } } diff --git a/test/fork/assets/USDC.t.sol b/test/fork/assets/USDC.t.sol index 0bfb0d7a..6e038fe4 100644 --- a/test/fork/assets/USDC.t.sol +++ b/test/fork/assets/USDC.t.sol @@ -6,30 +6,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { CreateWithMilestones_Batch_Fork_Test } from "../batch/createWithMilestones.t.sol"; import { CreateWithRange_Batch_Fork_Test } from "../batch/createWithRange.t.sol"; import { MerkleStreamerLL_Fork_Test } from "../merkle-streamer/MerkleStreamerLL.t.sol"; -import { - BatchCancelMultiple_TargetApprove_Fork_Test, - BatchCreate_TargetApprove_Fork_Test -} from "../target/TargetApprove.t.sol"; -import { - BatchCancelMultiple_TargetPermit2_Fork_Test, - BatchCreate_TargetPermit2_Fork_Test -} from "../target/TargetPermit2.t.sol"; -import { BatchCancelMultiple_TargetPush_Fork_Test, BatchCreate_TargetPush_Fork_Test } from "../target/TargetPush.t.sol"; IERC20 constant usdc = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); -contract USDC_BatchCancelMultiple_TargetApprove_Fork_Test is BatchCancelMultiple_TargetApprove_Fork_Test(usdc) { } - -contract USDC_BatchCancelMultiple_TargetPermit2_Fork_Test is BatchCancelMultiple_TargetPermit2_Fork_Test(usdc) { } - -contract USDC_BatchCancelMultiple_TargetPush_Fork_Test is BatchCancelMultiple_TargetPush_Fork_Test(usdc) { } - -contract USDC_BatchCreate_TargetApprove_Fork_Test is BatchCreate_TargetApprove_Fork_Test(usdc) { } - -contract USDC_BatchCreate_TargetPermit2_Fork_Test is BatchCreate_TargetPermit2_Fork_Test(usdc) { } - -contract USDC_BatchCreate_TargetPush_Fork_Test is BatchCreate_TargetPush_Fork_Test(usdc) { } - contract USDC_CreateWithMilestones_Batch_Fork_Test is CreateWithMilestones_Batch_Fork_Test(usdc) { } contract USDC_CreateWithRange_Batch_Fork_Test is CreateWithRange_Batch_Fork_Test(usdc) { } diff --git a/test/fork/assets/USDT.t.sol b/test/fork/assets/USDT.t.sol index 02a7fd96..423168d0 100644 --- a/test/fork/assets/USDT.t.sol +++ b/test/fork/assets/USDT.t.sol @@ -6,30 +6,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { CreateWithMilestones_Batch_Fork_Test } from "../batch/createWithMilestones.t.sol"; import { CreateWithRange_Batch_Fork_Test } from "../batch/createWithRange.t.sol"; import { MerkleStreamerLL_Fork_Test } from "../merkle-streamer/MerkleStreamerLL.t.sol"; -import { - BatchCancelMultiple_TargetApprove_Fork_Test, - BatchCreate_TargetApprove_Fork_Test -} from "../target/TargetApprove.t.sol"; -import { - BatchCancelMultiple_TargetPermit2_Fork_Test, - BatchCreate_TargetPermit2_Fork_Test -} from "../target/TargetPermit2.t.sol"; -import { BatchCancelMultiple_TargetPush_Fork_Test, BatchCreate_TargetPush_Fork_Test } from "../target/TargetPush.t.sol"; IERC20 constant usdt = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); -contract USDT_BatchCancelMultiple_TargetApprove_Fork_Test is BatchCancelMultiple_TargetApprove_Fork_Test(usdt) { } - -contract USDT_BatchCancelMultiple_TargetPermit2_Fork_Test is BatchCancelMultiple_TargetPermit2_Fork_Test(usdt) { } - -contract USDT_BatchCancelMultiple_TargetPush_Fork_Test is BatchCancelMultiple_TargetPush_Fork_Test(usdt) { } - -contract USDT_BatchCreate_TargetApprove_Fork_Test is BatchCreate_TargetApprove_Fork_Test(usdt) { } - -contract USDT_BatchCreate_TargetPermit2_Fork_Test is BatchCreate_TargetPermit2_Fork_Test(usdt) { } - -contract USDT_BatchCreate_TargetPush_Fork_Test is BatchCreate_TargetPush_Fork_Test(usdt) { } - contract USDT_CreateWithMilestones_Batch_Fork_Test is CreateWithMilestones_Batch_Fork_Test(usdt) { } contract USDT_CreateWithRange_Batch_Fork_Test is CreateWithRange_Batch_Fork_Test(usdt) { } diff --git a/test/fork/merkle-streamer/MerkleStreamerLL.t.sol b/test/fork/merkle-streamer/MerkleStreamerLL.t.sol index 8dc47cfa..b150be89 100644 --- a/test/fork/merkle-streamer/MerkleStreamerLL.t.sol +++ b/test/fork/merkle-streamer/MerkleStreamerLL.t.sol @@ -55,7 +55,7 @@ abstract contract MerkleStreamerLL_Fork_Test is Fork_Test { uint256[] public leaves; function testForkFuzz_MerkleStreamerLL(Params memory params) external { - vm.assume(params.admin != address(0) && params.admin != users.admin.addr); + vm.assume(params.admin != address(0) && params.admin != users.admin); vm.assume(params.expiration == 0 || params.expiration > block.timestamp); vm.assume(params.leafData.length > 1); params.posBeforeSort = _bound(params.posBeforeSort, 0, params.leafData.length - 1); diff --git a/test/fork/target/TargetApprove.t.sol b/test/fork/target/TargetApprove.t.sol deleted file mode 100644 index 5eb14d09..00000000 --- a/test/fork/target/TargetApprove.t.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Fork_Test } from "../Fork.t.sol"; -import { BatchCancelMultiple_Fork_Test } from "./batchCancelMultiple.t.sol"; -import { BatchCreate_Fork_Test } from "./batchCreate.t.sol"; -import { WrapAndCreate_Fork_Test } from "./wrapAndCreate.t.sol"; - -abstract contract TargetApprove_Fork_Test is Fork_Test { - function setUp() public virtual override { - Fork_Test.setUp(); - target = ISablierV2ProxyTarget(targetApprove); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCancelMultiple_TargetApprove_Fork_Test is - TargetApprove_Fork_Test, - BatchCancelMultiple_Fork_Test -{ - constructor(IERC20 asset_) BatchCancelMultiple_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetApprove_Fork_Test, BatchCancelMultiple_Fork_Test) { - TargetApprove_Fork_Test.setUp(); - BatchCancelMultiple_Fork_Test.setUp(); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCreate_TargetApprove_Fork_Test is TargetApprove_Fork_Test, BatchCreate_Fork_Test { - constructor(IERC20 asset_) BatchCreate_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetApprove_Fork_Test, BatchCreate_Fork_Test) { - TargetApprove_Fork_Test.setUp(); - BatchCreate_Fork_Test.setUp(); - } -} - -contract WrapAndCreate_TargetApprove_Fork_Test is TargetApprove_Fork_Test, WrapAndCreate_Fork_Test { - function setUp() public virtual override(TargetApprove_Fork_Test, WrapAndCreate_Fork_Test) { - TargetApprove_Fork_Test.setUp(); - WrapAndCreate_Fork_Test.setUp(); - } -} diff --git a/test/fork/target/TargetPermit2.t.sol b/test/fork/target/TargetPermit2.t.sol deleted file mode 100644 index 3e39f373..00000000 --- a/test/fork/target/TargetPermit2.t.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Fork_Test } from "../Fork.t.sol"; -import { BatchCancelMultiple_Fork_Test } from "./batchCancelMultiple.t.sol"; -import { BatchCreate_Fork_Test } from "./batchCreate.t.sol"; -import { WrapAndCreate_Fork_Test } from "./wrapAndCreate.t.sol"; - -abstract contract TargetPermit2_Fork_Test is Fork_Test { - function setUp() public virtual override { - Fork_Test.setUp(); - target = ISablierV2ProxyTarget(targetPermit2); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCancelMultiple_TargetPermit2_Fork_Test is - TargetPermit2_Fork_Test, - BatchCancelMultiple_Fork_Test -{ - constructor(IERC20 asset_) BatchCancelMultiple_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetPermit2_Fork_Test, BatchCancelMultiple_Fork_Test) { - TargetPermit2_Fork_Test.setUp(); - BatchCancelMultiple_Fork_Test.setUp(); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCreate_TargetPermit2_Fork_Test is TargetPermit2_Fork_Test, BatchCreate_Fork_Test { - constructor(IERC20 asset_) BatchCreate_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetPermit2_Fork_Test, BatchCreate_Fork_Test) { - TargetPermit2_Fork_Test.setUp(); - BatchCreate_Fork_Test.setUp(); - } -} - -contract WrapAndCreate_TargetPermit2_Fork_Test is TargetPermit2_Fork_Test, WrapAndCreate_Fork_Test { - function setUp() public virtual override(TargetPermit2_Fork_Test, WrapAndCreate_Fork_Test) { - TargetPermit2_Fork_Test.setUp(); - WrapAndCreate_Fork_Test.setUp(); - } -} diff --git a/test/fork/target/TargetPush.t.sol b/test/fork/target/TargetPush.t.sol deleted file mode 100644 index 621f73cd..00000000 --- a/test/fork/target/TargetPush.t.sol +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Fork_Test } from "../Fork.t.sol"; -import { BatchCancelMultiple_Fork_Test } from "./batchCancelMultiple.t.sol"; -import { BatchCreate_Fork_Test } from "./batchCreate.t.sol"; -import { WrapAndCreate_Fork_Test } from "./wrapAndCreate.t.sol"; - -abstract contract TargetPush_Fork_Test is Fork_Test { - function setUp() public virtual override { - Fork_Test.setUp(); - target = ISablierV2ProxyTarget(targetPush); - deal({ token: address(asset), to: address(aliceProxy), give: defaults.TOTAL_TRANSFER_AMOUNT() * 10 }); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCancelMultiple_TargetPush_Fork_Test is TargetPush_Fork_Test, BatchCancelMultiple_Fork_Test { - constructor(IERC20 asset_) BatchCancelMultiple_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetPush_Fork_Test, BatchCancelMultiple_Fork_Test) { - TargetPush_Fork_Test.setUp(); - BatchCancelMultiple_Fork_Test.setUp(); - } -} - -/// @dev Inherited by the asset contracts in "test/fork/assets" -abstract contract BatchCreate_TargetPush_Fork_Test is TargetPush_Fork_Test, BatchCreate_Fork_Test { - constructor(IERC20 asset_) BatchCreate_Fork_Test(asset_) { } - - function setUp() public virtual override(TargetPush_Fork_Test, BatchCreate_Fork_Test) { - TargetPush_Fork_Test.setUp(); - BatchCreate_Fork_Test.setUp(); - } -} - -contract WrapAndCreate_TargetPush_Fork_Test is TargetPush_Fork_Test, WrapAndCreate_Fork_Test { - function setUp() public virtual override(TargetPush_Fork_Test, WrapAndCreate_Fork_Test) { - TargetPush_Fork_Test.setUp(); - WrapAndCreate_Fork_Test.setUp(); - } -} diff --git a/test/fork/target/batchCancelMultiple.t.sol b/test/fork/target/batchCancelMultiple.t.sol deleted file mode 100644 index c1a07a90..00000000 --- a/test/fork/target/batchCancelMultiple.t.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { Lockup } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Batch } from "src/types/DataTypes.sol"; - -import { Fork_Test } from "../Fork.t.sol"; - -/// @dev Runs against multiple fork assets. -abstract contract BatchCancelMultiple_Fork_Test is Fork_Test { - constructor(IERC20 asset_) Fork_Test(asset_) { } - - function setUp() public virtual override { } - - function testForkFuzz_BatchCancelMultiple(uint256 batchSize) external { - batchSize = _bound(batchSize, 1, 50); - - // Create two batches of streams. - uint256[] memory dynamicStreamIds = batch.createWithMilestones({ - lockupDynamic: lockupDynamic, - asset: asset, - batch: defaults.batchCreateWithMilestones(batchSize) - }); - uint256[] memory linearStreamIds = batch.createWithRange({ - lockupLinear: lockupLinear, - asset: asset, - batch: defaults.batchCreateWithRange(batchSize) - }); - - // Simulate the passage of time. - vm.warp({ timestamp: defaults.CLIFF_TIME() }); - - // Expects calls to cancel multiple streams. - expectCallToCancelMultiple({ lockup: lockupDynamic, streamIds: dynamicStreamIds }); - expectCallToCancelMultiple({ lockup: lockupLinear, streamIds: linearStreamIds }); - - // Asset flow: Sablier → proxy → proxy owner - // Expects transfers from the Sablier contracts to the proxy, and then from the proxy to the proxy owner. - uint256 totalTransferAmount = 2 * defaults.REFUND_AMOUNT() * batchSize; - expectMultipleCallsToTransfer({ - count: uint64(2 * batchSize), - to: address(aliceProxy), - amount: defaults.REFUND_AMOUNT() - }); - expectCallToTransfer({ to: users.alice.addr, amount: totalTransferAmount }); - - // ABI encode the parameters and call the function via the proxy. - Batch.CancelMultiple[] memory batch = new Batch.CancelMultiple[](2); - batch[0] = Batch.CancelMultiple(lockupDynamic, dynamicStreamIds); - batch[1] = Batch.CancelMultiple(lockupLinear, linearStreamIds); - bytes memory data = abi.encodeCall(target.batchCancelMultiple, (batch, defaults.assets())); - aliceProxy.execute(address(target), data); - - // Assert that all streams have been canceled. - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - for (uint256 i = 0; i < batchSize; ++i) { - Lockup.Status actualDynamicStatus = lockupDynamic.statusOf(dynamicStreamIds[i]); - Lockup.Status actualLinearStatus = lockupLinear.statusOf(linearStreamIds[i]); - assertEq(actualDynamicStatus, expectedStatus, "lockupDynamic stream status not canceled"); - assertEq(actualLinearStatus, expectedStatus, "lockupLinear stream status not canceled"); - } - } -} diff --git a/test/fork/target/batchCreate.t.sol b/test/fork/target/batchCreate.t.sol deleted file mode 100644 index b908296f..00000000 --- a/test/fork/target/batchCreate.t.sol +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { PermitSignature } from "@uniswap/permit2-test/utils/PermitSignature.sol"; - -import { Batch } from "src/types/DataTypes.sol"; - -import { Fork_Test } from "../Fork.t.sol"; -import { ArrayBuilder } from "../../utils/ArrayBuilder.sol"; -import { BatchBuilder } from "../../utils/BatchBuilder.sol"; - -/// @dev Runs against multiple fork assets. -abstract contract BatchCreate_Fork_Test is Fork_Test, PermitSignature { - constructor(IERC20 asset_) Fork_Test(asset_) { } - - function setUp() public virtual override { } - - /*////////////////////////////////////////////////////////////////////////// - BATCH-CREATE-WITH-MILESTONES - //////////////////////////////////////////////////////////////////////////*/ - - struct CreateWithMilestonesParams { - uint128 batchSize; - address recipient; - uint128 perStreamAmount; - uint40 startTime; - LockupDynamic.Segment[] segments; - uint256 userPrivateKey; - } - - function testForkFuzz_BatchCreateWithMilestones(CreateWithMilestonesParams memory params) external { - vm.assume(params.segments.length != 0); - params.batchSize = boundUint128(params.batchSize, 1, 20); - params.startTime = boundUint40(params.startTime, getBlockTimestamp(), getBlockTimestamp() + 24 hours); - params.userPrivateKey = boundPrivateKey(params.userPrivateKey); - fuzzSegmentMilestones(params.segments, params.startTime); - (params.perStreamAmount,) = fuzzDynamicStreamAmounts({ - upperBound: MAX_UINT128 / params.batchSize, - segments: params.segments, - protocolFee: defaults.PROTOCOL_FEE(), - brokerFee: defaults.BROKER_FEE() - }); - - address user = vm.addr(params.userPrivateKey); - IPRBProxy userProxy = loadOrDeployProxy(user); - checkUsers(user, params.recipient, address(userProxy)); - - uint256 firstStreamId = lockupDynamic.nextStreamId(); - uint128 totalTransferAmount = params.perStreamAmount * params.batchSize; - - deal({ token: address(asset), to: user, give: uint256(totalTransferAmount) }); - changePrank({ msgSender: user }); - approveProxyOrPermit2(address(userProxy)); - - LockupDynamic.CreateWithMilestones memory createWithMilestones = LockupDynamic.CreateWithMilestones({ - asset: asset, - broker: defaults.broker(), - cancelable: true, - recipient: params.recipient, - segments: params.segments, - sender: address(userProxy), - startTime: params.startTime, - totalAmount: params.perStreamAmount, - transferable: true - }); - Batch.CreateWithMilestones[] memory batchParams = BatchBuilder.fillBatch(createWithMilestones, params.batchSize); - bytes memory transferData = target == targetPermit2 - ? defaults.permit2Params({ - user: user, - spender: address(userProxy), - amount: totalTransferAmount, - privateKey: params.userPrivateKey - }) - : bytes(""); - bytes memory data = - abi.encodeCall(target.batchCreateWithMilestones, (lockupDynamic, asset, batchParams, transferData)); - - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - if (target == targetPush) { - deal({ token: address(asset), to: address(userProxy), give: uint256(totalTransferAmount) }); - } else { - expectCallToTransferFrom({ - asset_: address(asset), - from: user, - to: address(userProxy), - amount: totalTransferAmount - }); - } - expectMultipleCallsToCreateWithMilestones({ count: uint64(params.batchSize), params: createWithMilestones }); - expectMultipleCallsToTransferFrom({ - asset_: address(asset), - count: uint64(params.batchSize), - from: address(userProxy), - to: address(lockupDynamic), - amount: params.perStreamAmount - }); - - bytes memory response = userProxy.execute(address(target), data); - uint256[] memory actualStreamIds = abi.decode(response, (uint256[])); - uint256[] memory expectedStreamIds = ArrayBuilder.fillStreamIds(firstStreamId, params.batchSize); - assertEq(actualStreamIds, expectedStreamIds); - } - - /*////////////////////////////////////////////////////////////////////////// - BATCH-CREATE-WITH-RANGE - //////////////////////////////////////////////////////////////////////////*/ - - struct CreateWithRangeParams { - uint128 batchSize; - LockupLinear.Range range; - address recipient; - uint128 perStreamAmount; - uint256 userPrivateKey; - } - - function testForkFuzz_BatchCreateWithRange(CreateWithRangeParams memory params) external { - params.batchSize = boundUint128(params.batchSize, 1, 20); - params.perStreamAmount = boundUint128(params.perStreamAmount, 1, MAX_UINT128 / params.batchSize); - params.range.start = boundUint40(params.range.start, getBlockTimestamp(), getBlockTimestamp() + 24 hours); - params.range.cliff = boundUint40(params.range.cliff, params.range.start, params.range.start + 52 weeks); - params.range.end = boundUint40(params.range.end, params.range.cliff + 1 seconds, MAX_UNIX_TIMESTAMP); - params.userPrivateKey = boundPrivateKey(params.userPrivateKey); - - address user = vm.addr(params.userPrivateKey); - IPRBProxy userProxy = loadOrDeployProxy(user); - checkUsers(user, params.recipient, address(userProxy)); - - uint256 firstStreamId = lockupLinear.nextStreamId(); - uint128 totalTransferAmount = params.perStreamAmount * params.batchSize; - - deal({ token: address(asset), to: user, give: uint256(totalTransferAmount) }); - changePrank({ msgSender: user }); - approveProxyOrPermit2(address(userProxy)); - - LockupLinear.CreateWithRange memory createParams = LockupLinear.CreateWithRange({ - asset: asset, - broker: defaults.broker(), - cancelable: true, - recipient: params.recipient, - sender: address(userProxy), - range: params.range, - totalAmount: params.perStreamAmount, - transferable: true - }); - Batch.CreateWithRange[] memory batchParams = BatchBuilder.fillBatch(createParams, params.batchSize); - bytes memory transferData = target == targetPermit2 - ? defaults.permit2Params({ - user: user, - spender: address(userProxy), - amount: totalTransferAmount, - privateKey: params.userPrivateKey - }) - : bytes(""); - bytes memory data = - abi.encodeCall(target.batchCreateWithRange, (lockupLinear, asset, batchParams, transferData)); - - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - if (target == targetPush) { - deal({ token: address(asset), to: address(userProxy), give: uint256(totalTransferAmount) }); - } else { - expectCallToTransferFrom({ - asset_: address(asset), - from: user, - to: address(userProxy), - amount: totalTransferAmount - }); - } - expectMultipleCallsToCreateWithRange({ count: uint64(params.batchSize), params: createParams }); - expectMultipleCallsToTransferFrom({ - asset_: address(asset), - count: uint64(params.batchSize), - from: address(userProxy), - to: address(lockupLinear), - amount: params.perStreamAmount - }); - - bytes memory response = userProxy.execute(address(target), data); - uint256[] memory actualStreamIds = abi.decode(response, (uint256[])); - uint256[] memory expectedStreamIds = ArrayBuilder.fillStreamIds(firstStreamId, params.batchSize); - assertEq(actualStreamIds, expectedStreamIds); - } -} diff --git a/test/fork/target/wrapAndCreate.t.sol b/test/fork/target/wrapAndCreate.t.sol deleted file mode 100644 index 0cf0a867..00000000 --- a/test/fork/target/wrapAndCreate.t.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { IWrappedNativeAsset } from "src/interfaces/IWrappedNativeAsset.sol"; - -import { Fork_Test } from "../Fork.t.sol"; - -/// @dev Runs against $WETH only. -abstract contract WrapAndCreate_Fork_Test is Fork_Test { - constructor() Fork_Test(IERC20(WETH_ADDRESS)) { } - - function setUp() public virtual override { } - - /*////////////////////////////////////////////////////////////////////////// - WRAP-AND-CREATE-WITH-MILESTONES - //////////////////////////////////////////////////////////////////////////*/ - - function testForkFuzz_WrapAndCreateWithMilestones(uint256 amount0, uint256 amount1) external { - uint256 max = users.alice.addr.balance - 1 ether; - amount0 = _bound(amount0, 1 wei, max / 2); - amount1 = _bound(amount1, 1 wei, max / 2); - uint256 totalAmount = amount0 + amount1; - - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupDynamic), - amount: totalAmount - }); - - LockupDynamic.CreateWithMilestones memory createParams = defaults.createWithMilestones(weth); - createParams.segments[0].amount = uint128(amount0); - createParams.segments[1].amount = uint128(amount1); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall(target.wrapAndCreateWithMilestones, (lockupDynamic, createParams)); - bytes memory response = aliceProxy.execute{ value: totalAmount }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupDynamic.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - WRAP-AND-CREATE-WITH-RANGE - //////////////////////////////////////////////////////////////////////////*/ - - function testForkFuzz_WrapAndCreateWithRange(uint256 etherAmount) external { - etherAmount = _bound(etherAmount, 1 wei, users.alice.addr.balance - 1 ether); - - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupLinear), - amount: etherAmount - }); - - // ABI encode the parameters and call the function via the proxy. - LockupLinear.CreateWithRange memory createParams = defaults.createWithRange(weth); - bytes memory data = abi.encodeCall(target.wrapAndCreateWithRange, (lockupLinear, createParams)); - bytes memory response = aliceProxy.execute{ value: etherAmount }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupLinear.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } -} diff --git a/test/integration/Integration.t.sol b/test/integration/Integration.t.sol index f343f062..05c6a0bc 100644 --- a/test/integration/Integration.t.sol +++ b/test/integration/Integration.t.sol @@ -1,15 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.19 <0.9.0; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; - -import { Precompiles as PRBProxyPrecompiles } from "@prb/proxy-test/utils/Precompiles.sol"; import { Precompiles as V2CorePrecompiles } from "@sablier/v2-core-test/utils/Precompiles.sol"; -import { DeployPermit2 } from "@uniswap/permit2-test/utils/DeployPermit2.sol"; import { Defaults } from "../utils/Defaults.sol"; -import { WETH } from "../mocks/WETH.sol"; -import { WLC } from "../mocks/WLC.sol"; import { Base_Test } from "../Base.t.sol"; /// @notice Common logic needed by all integration tests. @@ -26,7 +20,7 @@ abstract contract Integration_Test is Base_Test { deployDependencies(); // Deploy the defaults contract. - defaults = new Defaults(users, asset, permit2, aliceProxy); + defaults = new Defaults(users, asset); // Deploy V2 Periphery. deployPeripheryConditionally(); @@ -43,11 +37,6 @@ abstract contract Integration_Test is Base_Test { //////////////////////////////////////////////////////////////////////////*/ function deployDependencies() private { - weth = new WETH(); - wlc = new WLC(); - proxyRegistry = new PRBProxyPrecompiles().deployRegistry(); - aliceProxy = proxyRegistry.deployFor(users.alice.addr); - permit2 = IAllowanceTransfer(new DeployPermit2().run()); - (comptroller, lockupDynamic, lockupLinear,) = new V2CorePrecompiles().deployCore(users.admin.addr); + (comptroller, lockupDynamic, lockupLinear,) = new V2CorePrecompiles().deployCore(users.admin); } } diff --git a/test/integration/batch/create-with-deltas/createWithDeltas.t.sol b/test/integration/batch/create-with-deltas/createWithDeltas.t.sol index b0a5771b..11c51e4b 100644 --- a/test/integration/batch/create-with-deltas/createWithDeltas.t.sol +++ b/test/integration/batch/create-with-deltas/createWithDeltas.t.sol @@ -24,7 +24,7 @@ contract CreateWithDeltas_Integration_Test is Integration_Test { function test_BatchCreateWithDeltas() external whenBatchSizeNotZero { // Asset flow: Alice → batch → Sablier // Expect transfers from Alice to the batch, and then from the batch to the Sablier contract. - expectCallToTransferFrom({ from: users.alice.addr, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); + expectCallToTransferFrom({ from: users.alice, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); expectMultipleCallsToCreateWithDeltas({ count: defaults.BATCH_SIZE(), params: defaults.createWithDeltas() }); expectMultipleCallsToTransferFrom({ count: defaults.BATCH_SIZE(), diff --git a/test/integration/batch/create-with-durations/createWithDurations.t.sol b/test/integration/batch/create-with-durations/createWithDurations.t.sol index 6791483e..2aea5448 100644 --- a/test/integration/batch/create-with-durations/createWithDurations.t.sol +++ b/test/integration/batch/create-with-durations/createWithDurations.t.sol @@ -24,7 +24,7 @@ contract CreateWithDurations_Integration_Test is Integration_Test { function test_BatchCreateWithDurations() external whenBatchSizeNotZero { // Asset flow: Alice → batch → Sablier // Expect transfers from Alice to the batch, and then from the batch to the Sablier contract. - expectCallToTransferFrom({ from: users.alice.addr, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); + expectCallToTransferFrom({ from: users.alice, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); expectMultipleCallsToCreateWithDurations({ count: defaults.BATCH_SIZE(), params: defaults.createWithDurations() }); expectMultipleCallsToTransferFrom({ count: defaults.BATCH_SIZE(), diff --git a/test/integration/batch/create-with-milestones/createWithMilestones.t.sol b/test/integration/batch/create-with-milestones/createWithMilestones.t.sol index 8bc672f9..ca5b7383 100644 --- a/test/integration/batch/create-with-milestones/createWithMilestones.t.sol +++ b/test/integration/batch/create-with-milestones/createWithMilestones.t.sol @@ -24,7 +24,7 @@ contract CreateWithMilestones_Integration_Test is Integration_Test { function test_BatchCreateWithMilestones() external whenBatchSizeNotZero { // Asset flow: Alice → batch → Sablier // Expect transfers from Alice to the batch, and then from the batch to the Sablier contract. - expectCallToTransferFrom({ from: users.alice.addr, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); + expectCallToTransferFrom({ from: users.alice, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); expectMultipleCallsToCreateWithMilestones({ count: defaults.BATCH_SIZE(), params: defaults.createWithMilestones() diff --git a/test/integration/batch/create-with-range/createWithRange.t.sol b/test/integration/batch/create-with-range/createWithRange.t.sol index 0fe5f470..4f248bba 100644 --- a/test/integration/batch/create-with-range/createWithRange.t.sol +++ b/test/integration/batch/create-with-range/createWithRange.t.sol @@ -24,7 +24,7 @@ contract CreateWithRange_Integration_Test is Integration_Test { function test_CreateWithRange() external whenBatchSizeNotZero { // Asset flow: Alice → batch → Sablier // Expect transfers from Alice to the batch, and then from the batch to the Sablier contract. - expectCallToTransferFrom({ from: users.alice.addr, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); + expectCallToTransferFrom({ from: users.alice, to: address(batch), amount: defaults.TOTAL_TRANSFER_AMOUNT() }); expectMultipleCallsToCreateWithRange({ count: defaults.BATCH_SIZE(), params: defaults.createWithRange() }); expectMultipleCallsToTransferFrom({ count: defaults.BATCH_SIZE(), diff --git a/test/integration/merkle-streamer/MerkleStreamer.t.sol b/test/integration/merkle-streamer/MerkleStreamer.t.sol index 3abe2af1..fd6eeaaa 100644 --- a/test/integration/merkle-streamer/MerkleStreamer.t.sol +++ b/test/integration/merkle-streamer/MerkleStreamer.t.sol @@ -19,14 +19,14 @@ abstract contract MerkleStreamer_Integration_Test is Integration_Test { function claimLL() internal returns (uint256) { return merkleStreamerLL.claim({ index: defaults.INDEX1(), - recipient: users.recipient1.addr, + recipient: users.recipient1, amount: defaults.CLAIM_AMOUNT(), merkleProof: defaults.index1Proof() }); } function computeMerkleStreamerLLAddress() internal returns (address) { - return computeMerkleStreamerLLAddress(users.admin.addr, defaults.MERKLE_ROOT(), defaults.EXPIRATION()); + return computeMerkleStreamerLLAddress(users.admin, defaults.MERKLE_ROOT(), defaults.EXPIRATION()); } function computeMerkleStreamerLLAddress(address admin) internal returns (address) { @@ -42,7 +42,7 @@ abstract contract MerkleStreamer_Integration_Test is Integration_Test { } function createMerkleStreamerLL() internal returns (ISablierV2MerkleStreamerLL) { - return createMerkleStreamerLL(users.admin.addr, defaults.EXPIRATION()); + return createMerkleStreamerLL(users.admin, defaults.EXPIRATION()); } function createMerkleStreamerLL(address admin) internal returns (ISablierV2MerkleStreamerLL) { @@ -50,7 +50,7 @@ abstract contract MerkleStreamer_Integration_Test is Integration_Test { } function createMerkleStreamerLL(uint40 expiration) internal returns (ISablierV2MerkleStreamerLL) { - return createMerkleStreamerLL(users.admin.addr, expiration); + return createMerkleStreamerLL(users.admin, expiration); } function createMerkleStreamerLL(address admin, uint40 expiration) internal returns (ISablierV2MerkleStreamerLL) { diff --git a/test/integration/merkle-streamer/factory/create-merkle-streamer-ll/createMerkleStreamerLL.t.sol b/test/integration/merkle-streamer/factory/create-merkle-streamer-ll/createMerkleStreamerLL.t.sol index 70abcdbf..73d04060 100644 --- a/test/integration/merkle-streamer/factory/create-merkle-streamer-ll/createMerkleStreamerLL.t.sol +++ b/test/integration/merkle-streamer/factory/create-merkle-streamer-ll/createMerkleStreamerLL.t.sol @@ -25,7 +25,7 @@ contract CreateMerkleStreamerLL_Integration_Test is MerkleStreamer_Integration_T vm.expectRevert(); merkleStreamerFactory.createMerkleStreamerLL({ - initialAdmin: users.admin.addr, + initialAdmin: users.admin, lockupLinear: lockupLinear, asset: asset, merkleRoot: merkleRoot, @@ -44,7 +44,7 @@ contract CreateMerkleStreamerLL_Integration_Test is MerkleStreamer_Integration_T } function testFuzz_CreateMerkleStreamerLL(address admin, uint40 expiration) external givenNotAlreadyDeployed { - vm.assume(admin != users.admin.addr); + vm.assume(admin != users.admin); address expectedStreamerLL = computeMerkleStreamerLLAddress(admin, expiration); vm.expectEmit({ emitter: address(merkleStreamerFactory) }); diff --git a/test/integration/merkle-streamer/ll/claim/claim.t.sol b/test/integration/merkle-streamer/ll/claim/claim.t.sol index 1390696a..fcba315a 100644 --- a/test/integration/merkle-streamer/ll/claim/claim.t.sol +++ b/test/integration/merkle-streamer/ll/claim/claim.t.sol @@ -21,7 +21,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { vm.expectRevert( abi.encodeWithSelector(Errors.SablierV2MerkleStreamer_CampaignExpired.selector, warpTime, expiration) ); - merkleStreamerLL.claim({ index: 1, recipient: users.recipient1.addr, amount: 1, merkleProof: merkleProof }); + merkleStreamerLL.claim({ index: 1, recipient: users.recipient1, amount: 1, merkleProof: merkleProof }); } modifier givenCampaignNotExpired() { @@ -34,7 +34,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2MerkleStreamer_StreamClaimed.selector, index1)); - merkleStreamerLL.claim(index1, users.recipient1.addr, amount, merkleProof); + merkleStreamerLL.claim(index1, users.recipient1, amount, merkleProof); } modifier givenNotClaimed() { @@ -55,7 +55,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2MerkleStreamer_InvalidProof.selector)); - merkleStreamerLL.claim(invalidIndex, users.recipient1.addr, amount, merkleProof); + merkleStreamerLL.claim(invalidIndex, users.recipient1, amount, merkleProof); } function test_RevertWhen_InvalidRecipient() @@ -82,7 +82,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { uint128 invalidAmount = 1337; bytes32[] memory merkleProof = defaults.index1Proof(); vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2MerkleStreamer_InvalidProof.selector)); - merkleStreamerLL.claim(index1, users.recipient1.addr, invalidAmount, merkleProof); + merkleStreamerLL.claim(index1, users.recipient1, invalidAmount, merkleProof); } function test_RevertWhen_InvalidMerkleProof() @@ -95,7 +95,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { uint128 amount = defaults.CLAIM_AMOUNT(); bytes32[] memory invalidMerkleProof = defaults.index2Proof(); vm.expectRevert(abi.encodeWithSelector(Errors.SablierV2MerkleStreamer_InvalidProof.selector)); - merkleStreamerLL.claim(index1, users.recipient1.addr, amount, invalidMerkleProof); + merkleStreamerLL.claim(index1, users.recipient1, amount, invalidMerkleProof); } modifier givenIncludedInMerkleTree() { @@ -110,15 +110,10 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { { uint128 claimAmount = defaults.CLAIM_AMOUNT(); bytes32[] memory merkleProof = defaults.index1Proof(); - changePrank({ msgSender: users.admin.addr }); + changePrank({ msgSender: users.admin }); comptroller.setProtocolFee({ asset: asset, newProtocolFee: ud(0.1e18) }); vm.expectRevert(Errors.SablierV2MerkleStreamer_ProtocolFeeNotZero.selector); - merkleStreamerLL.claim({ - index: 1, - recipient: users.recipient1.addr, - amount: claimAmount, - merkleProof: merkleProof - }); + merkleStreamerLL.claim({ index: 1, recipient: users.recipient1, amount: claimAmount, merkleProof: merkleProof }); } modifier givenProtocolFeeZero() { @@ -135,7 +130,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { uint256 expectedStreamId = lockupLinear.nextStreamId(); vm.expectEmit({ emitter: address(merkleStreamerLL) }); - emit Claim(defaults.INDEX1(), users.recipient1.addr, defaults.CLAIM_AMOUNT(), expectedStreamId); + emit Claim(defaults.INDEX1(), users.recipient1, defaults.CLAIM_AMOUNT(), expectedStreamId); uint256 actualStreamId = claimLL(); LockupLinear.Stream memory actualStream = lockupLinear.getStream(actualStreamId); @@ -148,7 +143,7 @@ contract Claim_Integration_Test is MerkleStreamer_Integration_Test { isDepleted: false, isStream: true, isTransferable: defaults.TRANSFERABLE(), - sender: users.admin.addr, + sender: users.admin, startTime: uint40(block.timestamp), wasCanceled: false }); diff --git a/test/integration/merkle-streamer/ll/clawback/clawback.t.sol b/test/integration/merkle-streamer/ll/clawback/clawback.t.sol index c0b743cd..3094925e 100644 --- a/test/integration/merkle-streamer/ll/clawback/clawback.t.sol +++ b/test/integration/merkle-streamer/ll/clawback/clawback.t.sol @@ -14,13 +14,13 @@ contract Clawback_Integration_Test is MerkleStreamer_Integration_Test { } function test_RevertWhen_CallerNotAdmin() external { - changePrank({ msgSender: users.eve.addr }); - vm.expectRevert(abi.encodeWithSelector(V2CoreErrors.CallerNotAdmin.selector, users.admin.addr, users.eve.addr)); - merkleStreamerLL.clawback({ to: users.eve.addr, amount: 1 }); + changePrank({ msgSender: users.eve }); + vm.expectRevert(abi.encodeWithSelector(V2CoreErrors.CallerNotAdmin.selector, users.admin, users.eve)); + merkleStreamerLL.clawback({ to: users.eve, amount: 1 }); } modifier whenCallerAdmin() { - changePrank({ msgSender: users.admin.addr }); + changePrank({ msgSender: users.admin }); _; } @@ -34,7 +34,7 @@ contract Clawback_Integration_Test is MerkleStreamer_Integration_Test { Errors.SablierV2MerkleStreamer_CampaignNotExpired.selector, block.timestamp, defaults.EXPIRATION() ) ); - merkleStreamerLL.clawback({ to: users.admin.addr, amount: 1 }); + merkleStreamerLL.clawback({ to: users.admin, amount: 1 }); } modifier givenCampaignExpired() { @@ -45,7 +45,7 @@ contract Clawback_Integration_Test is MerkleStreamer_Integration_Test { } function test_Clawback() external whenCallerAdmin givenProtocolFeeZero givenCampaignExpired { - test_Clawback(users.admin.addr); + test_Clawback(users.admin); } modifier givenProtocolFeeNotZero() { @@ -67,7 +67,7 @@ contract Clawback_Integration_Test is MerkleStreamer_Integration_Test { uint128 clawbackAmount = uint128(asset.balanceOf(address(merkleStreamerLL))); expectCallToTransfer({ to: to, amount: clawbackAmount }); vm.expectEmit({ emitter: address(merkleStreamerLL) }); - emit Clawback({ admin: users.admin.addr, to: to, amount: clawbackAmount }); + emit Clawback({ admin: users.admin, to: to, amount: clawbackAmount }); merkleStreamerLL.clawback({ to: to, amount: clawbackAmount }); } } diff --git a/test/integration/merkle-streamer/ll/constructor/constructor.t.sol b/test/integration/merkle-streamer/ll/constructor/constructor.t.sol index c7ea566e..676b9d18 100644 --- a/test/integration/merkle-streamer/ll/constructor/constructor.t.sol +++ b/test/integration/merkle-streamer/ll/constructor/constructor.t.sol @@ -32,7 +32,7 @@ contract Constructor_MerkleStreamerLL_Integration_Test is MerkleStreamer_Integra function test_Constructor() external { SablierV2MerkleStreamerLL constructedStreamerLL = new SablierV2MerkleStreamerLL( - users.admin.addr, + users.admin, lockupLinear, asset, defaults.MERKLE_ROOT(), @@ -45,7 +45,7 @@ contract Constructor_MerkleStreamerLL_Integration_Test is MerkleStreamer_Integra Vars memory vars; vars.actualAdmin = constructedStreamerLL.admin(); - vars.expectedAdmin = users.admin.addr; + vars.expectedAdmin = users.admin; assertEq(vars.actualAdmin, vars.expectedAdmin, "admin"); vars.actualAsset = address(constructedStreamerLL.ASSET()); diff --git a/test/integration/target/Target.t.sol b/test/integration/target/Target.t.sol deleted file mode 100644 index 905e9747..00000000 --- a/test/integration/target/Target.t.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.20 <0.9.0; - -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Integration_Test } from "../Integration.t.sol"; - -abstract contract Target_Integration_Test is Integration_Test { - function setUp() public virtual override { - Integration_Test.setUp(); - } - - function batchCreateWithDeltas() internal returns (uint256[] memory) { - bytes memory data = abi.encodeCall( - target.batchCreateWithDeltas, - (lockupDynamic, asset, defaults.batchCreateWithDeltas(), getTransferData(defaults.TOTAL_TRANSFER_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function batchCreateWithDurations() internal returns (uint256[] memory) { - bytes memory data = abi.encodeCall( - target.batchCreateWithDurations, - ( - lockupLinear, - asset, - defaults.batchCreateWithDurations(), - getTransferData(defaults.TOTAL_TRANSFER_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function batchCreateWithMilestones() internal returns (uint256[] memory) { - bytes memory data = abi.encodeCall( - target.batchCreateWithMilestones, - ( - lockupDynamic, - asset, - defaults.batchCreateWithMilestones(), - getTransferData(defaults.TOTAL_TRANSFER_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function batchCreateWithMilestones(uint256 batchSize) internal returns (uint256[] memory) { - uint128 totalTransferAmount = uint128(batchSize) * defaults.PER_STREAM_AMOUNT(); - bytes memory data = abi.encodeCall( - target.batchCreateWithMilestones, - (lockupDynamic, asset, defaults.batchCreateWithMilestones(batchSize), getTransferData(totalTransferAmount)) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function batchCreateWithRange() internal returns (uint256[] memory) { - bytes memory data = abi.encodeCall( - target.batchCreateWithRange, - (lockupLinear, asset, defaults.batchCreateWithRange(), getTransferData(defaults.TOTAL_TRANSFER_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function batchCreateWithRange(uint256 batchSize) internal returns (uint256[] memory) { - uint128 totalTransferAmount = uint128(batchSize) * defaults.PER_STREAM_AMOUNT(); - bytes memory data = abi.encodeCall( - target.batchCreateWithRange, - (lockupLinear, asset, defaults.batchCreateWithRange(batchSize), getTransferData(totalTransferAmount)) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256[])); - } - - function createWithDeltas() internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithDeltas, - (lockupDynamic, defaults.createWithDeltas(), getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function createWithDurations() internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithDurations, - (lockupLinear, defaults.createWithDurations(), getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function createWithMilestones() internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithMilestones, - (lockupDynamic, defaults.createWithMilestones(), getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function createWithMilestones(LockupDynamic.CreateWithMilestones memory params) internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithMilestones, (lockupDynamic, params, getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function createWithRange() internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithRange, - (lockupLinear, defaults.createWithRange(), getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function createWithRange(LockupLinear.CreateWithRange memory params) internal returns (uint256) { - bytes memory data = abi.encodeCall( - target.createWithRange, (lockupLinear, params, getTransferData(defaults.PER_STREAM_AMOUNT())) - ); - bytes memory response = aliceProxy.execute(address(target), data); - return abi.decode(response, (uint256)); - } - - function getTransferData(uint160 amount) internal view returns (bytes memory) { - if (target == targetPermit2) { - return defaults.permit2Params(amount); - } - // The {ProxyTargetApprove} contract does not require any transfer data. - return bytes(""); - } -} diff --git a/test/integration/target/TargetApprove.t.sol b/test/integration/target/TargetApprove.t.sol deleted file mode 100644 index 263ef55b..00000000 --- a/test/integration/target/TargetApprove.t.sol +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Integration_Test } from "../Integration.t.sol"; -import { BatchCancelMultiple_Integration_Test } from "./batch-cancel-multiple/batchCancelMultiple.t.sol"; -import { BatchCreateWithDeltas_Integration_Test } from "./batch-create-with-deltas/batchCreateWithDeltas.t.sol"; -import { BatchCreateWithDurations_Integration_Test } from "./batch-create-with-durations/batchCreateWithDurations.t.sol"; -import { BatchCreateWithMilestones_Integration_Test } from - "./batch-create-with-milestones/batchCreateWithMilestones.t.sol"; -import { BatchCreateWithRange_Integration_Test } from "./batch-create-with-range/batchCreateWithRange.t.sol"; -import { Burn_Integration_Test } from "./burn/burn.t.sol"; -import { Cancel_Integration_Test } from "./cancel/cancel.t.sol"; -import { CancelAndCreate_Integration_Test } from "./cancel-and-create/cancelAndCreate.t.sol"; -import { CancelMultiple_Integration_Test } from "./cancel-multiple/cancelMultiple.t.sol"; -import { Renounce_Integration_Test } from "./renounce/renounce.t.sol"; -import { Withdraw_Integration_Test } from "./withdraw/withdraw.t.sol"; -import { WithdrawMax_Integration_Test } from "./withdraw-max/withdrawMax.t.sol"; -import { WithdrawMaxAndTransfer_Integration_Test } from "./withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol"; -import { WithdrawMultiple_Integration_Test } from "./withdraw-multiple/withdrawMultiple.t.sol"; -import { WrapAndCreate_Integration_Test } from "./wrap-and-create/wrapAndCreate.t.sol"; - -abstract contract TargetApprove_Integration_Test is Integration_Test { - function setUp() public virtual override { - Integration_Test.setUp(); - target = ISablierV2ProxyTarget(targetApprove); - } -} - -contract BatchCancelMultiple_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - BatchCancelMultiple_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, BatchCancelMultiple_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - BatchCancelMultiple_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDeltas_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - BatchCreateWithDeltas_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, BatchCreateWithDeltas_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - BatchCreateWithDeltas_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDurations_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - BatchCreateWithDurations_Integration_Test -{ - function setUp() - public - virtual - override(TargetApprove_Integration_Test, BatchCreateWithDurations_Integration_Test) - { - TargetApprove_Integration_Test.setUp(); - BatchCreateWithDurations_Integration_Test.setUp(); - } -} - -contract BatchCreateWithMilestones_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - BatchCreateWithMilestones_Integration_Test -{ - function setUp() - public - virtual - override(TargetApprove_Integration_Test, BatchCreateWithMilestones_Integration_Test) - { - TargetApprove_Integration_Test.setUp(); - BatchCreateWithMilestones_Integration_Test.setUp(); - } -} - -contract BatchCreateWithRange_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - BatchCreateWithRange_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, BatchCreateWithRange_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - BatchCreateWithRange_Integration_Test.setUp(); - } -} - -contract Burn_TargetApprove_Integration_Test is TargetApprove_Integration_Test, Burn_Integration_Test { - function setUp() public virtual override(TargetApprove_Integration_Test, Burn_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - Burn_Integration_Test.setUp(); - } -} - -contract Cancel_TargetApprove_Integration_Test is TargetApprove_Integration_Test, Cancel_Integration_Test { - function setUp() public virtual override(TargetApprove_Integration_Test, Cancel_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - Cancel_Integration_Test.setUp(); - } -} - -contract CancelAndCreate_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - CancelAndCreate_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, CancelAndCreate_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - CancelAndCreate_Integration_Test.setUp(); - } -} - -contract CancelMultiple_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - CancelMultiple_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, CancelMultiple_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - CancelMultiple_Integration_Test.setUp(); - } -} - -contract Renounce_TargetApprove_Integration_Test is TargetApprove_Integration_Test, Renounce_Integration_Test { - function setUp() public virtual override(TargetApprove_Integration_Test, Renounce_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - Renounce_Integration_Test.setUp(); - } -} - -contract Withdraw_TargetApprove_Integration_Test is TargetApprove_Integration_Test, Withdraw_Integration_Test { - function setUp() public virtual override(TargetApprove_Integration_Test, Withdraw_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - Withdraw_Integration_Test.setUp(); - } -} - -contract WithdrawMax_TargetApprove_Integration_Test is TargetApprove_Integration_Test, WithdrawMax_Integration_Test { - function setUp() public virtual override(TargetApprove_Integration_Test, WithdrawMax_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - WithdrawMax_Integration_Test.setUp(); - } -} - -contract WithdrawMaxAndTransfer_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - WithdrawMaxAndTransfer_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, WithdrawMaxAndTransfer_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - WithdrawMaxAndTransfer_Integration_Test.setUp(); - } -} - -contract WithdrawMultiple_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - WithdrawMultiple_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, WithdrawMultiple_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - WithdrawMultiple_Integration_Test.setUp(); - } -} - -contract WrapAndCreate_TargetApprove_Integration_Test is - TargetApprove_Integration_Test, - WrapAndCreate_Integration_Test -{ - function setUp() public virtual override(TargetApprove_Integration_Test, WrapAndCreate_Integration_Test) { - TargetApprove_Integration_Test.setUp(); - WrapAndCreate_Integration_Test.setUp(); - } -} diff --git a/test/integration/target/TargetPermit2.t.sol b/test/integration/target/TargetPermit2.t.sol deleted file mode 100644 index c578190a..00000000 --- a/test/integration/target/TargetPermit2.t.sol +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Integration_Test } from "../Integration.t.sol"; -import { BatchCancelMultiple_Integration_Test } from "./batch-cancel-multiple/batchCancelMultiple.t.sol"; -import { BatchCreateWithDeltas_Integration_Test } from "./batch-create-with-deltas/batchCreateWithDeltas.t.sol"; -import { BatchCreateWithDurations_Integration_Test } from "./batch-create-with-durations/batchCreateWithDurations.t.sol"; -import { BatchCreateWithMilestones_Integration_Test } from - "./batch-create-with-milestones/batchCreateWithMilestones.t.sol"; -import { BatchCreateWithRange_Integration_Test } from "./batch-create-with-range/batchCreateWithRange.t.sol"; -import { Burn_Integration_Test } from "./burn/burn.t.sol"; -import { Cancel_Integration_Test } from "./cancel/cancel.t.sol"; -import { CancelAndCreate_Integration_Test } from "./cancel-and-create/cancelAndCreate.t.sol"; -import { CancelMultiple_Integration_Test } from "./cancel-multiple/cancelMultiple.t.sol"; -import { Renounce_Integration_Test } from "./renounce/renounce.t.sol"; -import { Withdraw_Integration_Test } from "./withdraw/withdraw.t.sol"; -import { WithdrawMax_Integration_Test } from "./withdraw-max/withdrawMax.t.sol"; -import { WithdrawMaxAndTransfer_Integration_Test } from "./withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol"; -import { WithdrawMultiple_Integration_Test } from "./withdraw-multiple/withdrawMultiple.t.sol"; -import { WrapAndCreate_Integration_Test } from "./wrap-and-create/wrapAndCreate.t.sol"; - -abstract contract TargetPermit2_Integration_Test is Integration_Test { - function setUp() public virtual override { - Integration_Test.setUp(); - target = ISablierV2ProxyTarget(targetPermit2); - } -} - -contract BatchCancelMultiple_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - BatchCancelMultiple_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, BatchCancelMultiple_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - BatchCancelMultiple_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDeltas_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - BatchCreateWithDeltas_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, BatchCreateWithDeltas_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - BatchCreateWithDeltas_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDurations_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - BatchCreateWithDurations_Integration_Test -{ - function setUp() - public - virtual - override(TargetPermit2_Integration_Test, BatchCreateWithDurations_Integration_Test) - { - TargetPermit2_Integration_Test.setUp(); - BatchCreateWithDurations_Integration_Test.setUp(); - } -} - -contract BatchCreateWithMilestones_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - BatchCreateWithMilestones_Integration_Test -{ - function setUp() - public - virtual - override(TargetPermit2_Integration_Test, BatchCreateWithMilestones_Integration_Test) - { - TargetPermit2_Integration_Test.setUp(); - BatchCreateWithMilestones_Integration_Test.setUp(); - } -} - -contract BatchCreateWithRange_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - BatchCreateWithRange_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, BatchCreateWithRange_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - BatchCreateWithRange_Integration_Test.setUp(); - } -} - -contract Burn_TargetPermit2_Integration_Test is TargetPermit2_Integration_Test, Burn_Integration_Test { - function setUp() public virtual override(TargetPermit2_Integration_Test, Burn_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - Burn_Integration_Test.setUp(); - } -} - -contract Cancel_TargetPermit2_Integration_Test is TargetPermit2_Integration_Test, Cancel_Integration_Test { - function setUp() public virtual override(TargetPermit2_Integration_Test, Cancel_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - Cancel_Integration_Test.setUp(); - } -} - -contract CancelAndCreate_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - CancelAndCreate_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, CancelAndCreate_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - CancelAndCreate_Integration_Test.setUp(); - } -} - -contract CancelMultiple_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - CancelMultiple_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, CancelMultiple_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - CancelMultiple_Integration_Test.setUp(); - } -} - -contract Renounce_TargetPermit2_Integration_Test is TargetPermit2_Integration_Test, Renounce_Integration_Test { - function setUp() public virtual override(TargetPermit2_Integration_Test, Renounce_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - Renounce_Integration_Test.setUp(); - } -} - -contract Withdraw_TargetPermit2_Integration_Test is TargetPermit2_Integration_Test, Withdraw_Integration_Test { - function setUp() public virtual override(TargetPermit2_Integration_Test, Withdraw_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - Withdraw_Integration_Test.setUp(); - } -} - -contract WithdrawMax_TargetPermit2_Integration_Test is TargetPermit2_Integration_Test, WithdrawMax_Integration_Test { - function setUp() public virtual override(TargetPermit2_Integration_Test, WithdrawMax_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - WithdrawMax_Integration_Test.setUp(); - } -} - -contract WithdrawMaxAndTransfer_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - WithdrawMaxAndTransfer_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, WithdrawMaxAndTransfer_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - WithdrawMaxAndTransfer_Integration_Test.setUp(); - } -} - -contract WithdrawMultiple_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - WithdrawMultiple_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, WithdrawMultiple_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - WithdrawMultiple_Integration_Test.setUp(); - } -} - -contract WrapAndCreate_TargetPermit2_Integration_Test is - TargetPermit2_Integration_Test, - WrapAndCreate_Integration_Test -{ - function setUp() public virtual override(TargetPermit2_Integration_Test, WrapAndCreate_Integration_Test) { - TargetPermit2_Integration_Test.setUp(); - WrapAndCreate_Integration_Test.setUp(); - } -} diff --git a/test/integration/target/TargetPush.t.sol b/test/integration/target/TargetPush.t.sol deleted file mode 100644 index 4bc69558..00000000 --- a/test/integration/target/TargetPush.t.sol +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2ProxyTarget } from "src/interfaces/ISablierV2ProxyTarget.sol"; - -import { Integration_Test } from "../Integration.t.sol"; -import { BatchCancelMultiple_Integration_Test } from "./batch-cancel-multiple/batchCancelMultiple.t.sol"; -import { BatchCreateWithDeltas_Integration_Test } from "./batch-create-with-deltas/batchCreateWithDeltas.t.sol"; -import { BatchCreateWithDurations_Integration_Test } from "./batch-create-with-durations/batchCreateWithDurations.t.sol"; -import { BatchCreateWithMilestones_Integration_Test } from - "./batch-create-with-milestones/batchCreateWithMilestones.t.sol"; -import { BatchCreateWithRange_Integration_Test } from "./batch-create-with-range/batchCreateWithRange.t.sol"; -import { Burn_Integration_Test } from "./burn/burn.t.sol"; -import { Cancel_Integration_Test } from "./cancel/cancel.t.sol"; -import { CancelAndCreate_Integration_Test } from "./cancel-and-create/cancelAndCreate.t.sol"; -import { CancelMultiple_Integration_Test } from "./cancel-multiple/cancelMultiple.t.sol"; -import { Renounce_Integration_Test } from "./renounce/renounce.t.sol"; -import { Withdraw_Integration_Test } from "./withdraw/withdraw.t.sol"; -import { WithdrawMax_Integration_Test } from "./withdraw-max/withdrawMax.t.sol"; -import { WithdrawMaxAndTransfer_Integration_Test } from "./withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol"; -import { WithdrawMultiple_Integration_Test } from "./withdraw-multiple/withdrawMultiple.t.sol"; -import { WrapAndCreate_Integration_Test } from "./wrap-and-create/wrapAndCreate.t.sol"; - -abstract contract TargetPush_Integration_Test is Integration_Test { - function setUp() public virtual override { - Integration_Test.setUp(); - target = ISablierV2ProxyTarget(targetPush); - asset.transfer({ to: address(aliceProxy), amount: 2 * defaults.TOTAL_TRANSFER_AMOUNT() }); - } -} - -contract BatchCancelMultiple_TargetPush_Integration_Test is - TargetPush_Integration_Test, - BatchCancelMultiple_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, BatchCancelMultiple_Integration_Test) { - TargetPush_Integration_Test.setUp(); - BatchCancelMultiple_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDeltas_TargetPush_Integration_Test is - TargetPush_Integration_Test, - BatchCreateWithDeltas_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, BatchCreateWithDeltas_Integration_Test) { - TargetPush_Integration_Test.setUp(); - BatchCreateWithDeltas_Integration_Test.setUp(); - } -} - -contract BatchCreateWithDurations_TargetPush_Integration_Test is - TargetPush_Integration_Test, - BatchCreateWithDurations_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, BatchCreateWithDurations_Integration_Test) { - TargetPush_Integration_Test.setUp(); - BatchCreateWithDurations_Integration_Test.setUp(); - } -} - -contract BatchCreateWithMilestones_TargetPush_Integration_Test is - TargetPush_Integration_Test, - BatchCreateWithMilestones_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, BatchCreateWithMilestones_Integration_Test) { - TargetPush_Integration_Test.setUp(); - BatchCreateWithMilestones_Integration_Test.setUp(); - } -} - -contract BatchCreateWithRange_TargetPush_Integration_Test is - TargetPush_Integration_Test, - BatchCreateWithRange_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, BatchCreateWithRange_Integration_Test) { - TargetPush_Integration_Test.setUp(); - BatchCreateWithRange_Integration_Test.setUp(); - } -} - -contract Burn_TargetPush_Integration_Test is TargetPush_Integration_Test, Burn_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, Burn_Integration_Test) { - TargetPush_Integration_Test.setUp(); - Burn_Integration_Test.setUp(); - } -} - -contract Cancel_TargetPush_Integration_Test is TargetPush_Integration_Test, Cancel_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, Cancel_Integration_Test) { - TargetPush_Integration_Test.setUp(); - Cancel_Integration_Test.setUp(); - } -} - -contract CancelAndCreate_TargetPush_Integration_Test is - TargetPush_Integration_Test, - CancelAndCreate_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, CancelAndCreate_Integration_Test) { - TargetPush_Integration_Test.setUp(); - CancelAndCreate_Integration_Test.setUp(); - } -} - -contract CancelMultiple_TargetPush_Integration_Test is TargetPush_Integration_Test, CancelMultiple_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, CancelMultiple_Integration_Test) { - TargetPush_Integration_Test.setUp(); - CancelMultiple_Integration_Test.setUp(); - } -} - -contract Renounce_TargetPush_Integration_Test is TargetPush_Integration_Test, Renounce_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, Renounce_Integration_Test) { - TargetPush_Integration_Test.setUp(); - Renounce_Integration_Test.setUp(); - } -} - -contract Withdraw_TargetPush_Integration_Test is TargetPush_Integration_Test, Withdraw_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, Withdraw_Integration_Test) { - TargetPush_Integration_Test.setUp(); - Withdraw_Integration_Test.setUp(); - } -} - -contract WithdrawMax_TargetPush_Integration_Test is TargetPush_Integration_Test, WithdrawMax_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, WithdrawMax_Integration_Test) { - TargetPush_Integration_Test.setUp(); - WithdrawMax_Integration_Test.setUp(); - } -} - -contract WithdrawMaxAndTransfer_TargetPush_Integration_Test is - TargetPush_Integration_Test, - WithdrawMaxAndTransfer_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, WithdrawMaxAndTransfer_Integration_Test) { - TargetPush_Integration_Test.setUp(); - WithdrawMaxAndTransfer_Integration_Test.setUp(); - } -} - -contract WithdrawMultiple_TargetPush_Integration_Test is - TargetPush_Integration_Test, - WithdrawMultiple_Integration_Test -{ - function setUp() public virtual override(TargetPush_Integration_Test, WithdrawMultiple_Integration_Test) { - TargetPush_Integration_Test.setUp(); - WithdrawMultiple_Integration_Test.setUp(); - } -} - -contract WrapAndCreate_TargetPush_Integration_Test is TargetPush_Integration_Test, WrapAndCreate_Integration_Test { - function setUp() public virtual override(TargetPush_Integration_Test, WrapAndCreate_Integration_Test) { - TargetPush_Integration_Test.setUp(); - WrapAndCreate_Integration_Test.setUp(); - } -} diff --git a/test/integration/target/batch-cancel-multiple/batchCancelMultiple.t.sol b/test/integration/target/batch-cancel-multiple/batchCancelMultiple.t.sol deleted file mode 100644 index 269febcd..00000000 --- a/test/integration/target/batch-cancel-multiple/batchCancelMultiple.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { Lockup } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; -import { Batch } from "src/types/DataTypes.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract BatchCancelMultiple_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - Batch.CancelMultiple[] memory batchParams; - IERC20[] memory assets = defaults.assets(); - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.batchCancelMultiple(batchParams, assets); - } - - modifier whenDelegateCalled() { - _; - } - - function test_RevertWhen_BatchSizeZero() external whenDelegateCalled { - Batch.CancelMultiple[] memory batchParams = new Batch.CancelMultiple[](0); - bytes memory data = abi.encodeCall(target.batchCancelMultiple, (batchParams, defaults.assets())); - vm.expectRevert(Errors.SablierV2ProxyTarget_BatchSizeZero.selector); - aliceProxy.execute(address(target), data); - } - - modifier batchSizeNotZero() { - _; - } - - function test_BatchCancelMultiple() external batchSizeNotZero whenDelegateCalled { - // Create two batches of streams to be canceled. - uint256[] memory dynamicStreamIds = batchCreateWithMilestones(); - uint256[] memory linearStreamIds = batchCreateWithRange(); - - // Simulate the passage of time. - vm.warp({ timestamp: defaults.CLIFF_TIME() }); - - // Expects calls to cancel multiple streams. - expectCallToCancelMultiple({ lockup: lockupDynamic, streamIds: dynamicStreamIds }); - expectCallToCancelMultiple({ lockup: lockupLinear, streamIds: linearStreamIds }); - - // Asset flow: Sablier → proxy → proxy owner - // Expects transfers from the Sablier contracts to the proxy, and then from the proxy to the proxy owner. - expectMultipleCallsToTransfer({ - count: 2 * defaults.BATCH_SIZE(), - to: address(aliceProxy), - amount: defaults.REFUND_AMOUNT() - }); - expectCallToTransfer({ to: users.alice.addr, amount: 2 * defaults.REFUND_AMOUNT() * defaults.BATCH_SIZE() }); - - // ABI encode the parameters and call the function via the proxy. - Batch.CancelMultiple[] memory batchParams = new Batch.CancelMultiple[](2); - batchParams[0] = Batch.CancelMultiple(lockupDynamic, dynamicStreamIds); - batchParams[1] = Batch.CancelMultiple(lockupLinear, linearStreamIds); - bytes memory data = abi.encodeCall(target.batchCancelMultiple, (batchParams, defaults.assets())); - aliceProxy.execute(address(target), data); - - // Assert that all streams have been canceled. - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) { - Lockup.Status actualDynamicStatus = lockupDynamic.statusOf(dynamicStreamIds[i]); - Lockup.Status actualLinearStatus = lockupLinear.statusOf(linearStreamIds[i]); - assertEq(actualDynamicStatus, expectedStatus, "lockupDynamic stream status not canceled"); - assertEq(actualLinearStatus, expectedStatus, "lockupLinear stream status not canceled"); - } - } -} diff --git a/test/integration/target/batch-cancel-multiple/batchCancelMultiple.tree b/test/integration/target/batch-cancel-multiple/batchCancelMultiple.tree deleted file mode 100644 index 091d7622..00000000 --- a/test/integration/target/batch-cancel-multiple/batchCancelMultiple.tree +++ /dev/null @@ -1,9 +0,0 @@ -batchCancelMultiple.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the batch size is zero - │ └── it should revert - └── when the batch size is not zero - ├── it should batch cancel multiple - └── it should perform the ERC-20 transfers diff --git a/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.t.sol b/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.t.sol deleted file mode 100644 index cfa48257..00000000 --- a/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.t.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { Errors } from "src/libraries/Errors.sol"; -import { Batch } from "src/types/DataTypes.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract BatchCreateWithDeltas_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - Batch.CreateWithDeltas[] memory batchParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.batchCreateWithDeltas({ - lockupDynamic: lockupDynamic, - asset: asset, - batch: batchParams, - transferData: bytes("") - }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_RevertWhen_BatchSizeZero() external whenDelegateCalled { - Batch.CreateWithDeltas[] memory batchParams = new Batch.CreateWithDeltas[](0); - bytes memory data = abi.encodeCall(target.batchCreateWithDeltas, (lockupDynamic, asset, batchParams, bytes(""))); - vm.expectRevert(Errors.SablierV2ProxyTarget_BatchSizeZero.selector); - aliceProxy.execute(address(target), data); - } - - modifier whenBatchSizeNotZero() { - _; - } - - function test_BatchCreateWithDeltas() external whenBatchSizeNotZero whenDelegateCalled { - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - expectCallToTransferFrom({ - from: users.alice.addr, - to: address(aliceProxy), - amount: defaults.TOTAL_TRANSFER_AMOUNT() - }); - expectMultipleCallsToCreateWithDeltas({ count: defaults.BATCH_SIZE(), params: defaults.createWithDeltas() }); - expectMultipleCallsToTransferFrom({ - count: defaults.BATCH_SIZE(), - from: address(aliceProxy), - to: address(lockupDynamic), - amount: defaults.PER_STREAM_AMOUNT() - }); - - // Assert that the batch of streams has been created successfully. - uint256[] memory actualStreamIds = batchCreateWithDeltas(); - uint256[] memory expectedStreamIds = defaults.incrementalStreamIds(); - assertEq(actualStreamIds, expectedStreamIds, "stream ids mismatch"); - } -} diff --git a/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.tree b/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.tree deleted file mode 100644 index 19e92753..00000000 --- a/test/integration/target/batch-create-with-deltas/batchCreateWithDeltas.tree +++ /dev/null @@ -1,9 +0,0 @@ -batchCreateWithDeltas.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the batch size is zero - │ └── it should revert - └── when the batch size is not zero - ├── it should create a batch of streams with deltas - └── it should perform the ERC-20 transfers diff --git a/test/integration/target/batch-create-with-durations/batchCreateWithDurations.t.sol b/test/integration/target/batch-create-with-durations/batchCreateWithDurations.t.sol deleted file mode 100644 index dbd0003a..00000000 --- a/test/integration/target/batch-create-with-durations/batchCreateWithDurations.t.sol +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { Errors } from "src/libraries/Errors.sol"; -import { Batch } from "src/types/DataTypes.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract BatchCreateWithDurations_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - Batch.CreateWithDurations[] memory batchParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.batchCreateWithDurations({ - lockupLinear: lockupLinear, - asset: asset, - batch: batchParams, - transferData: bytes("") - }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_RevertWhen_BatchSizeZero() external whenDelegateCalled { - Batch.CreateWithDurations[] memory batchParams = new Batch.CreateWithDurations[](0); - bytes memory data = - abi.encodeCall(target.batchCreateWithDurations, (lockupLinear, asset, batchParams, bytes(""))); - vm.expectRevert(Errors.SablierV2ProxyTarget_BatchSizeZero.selector); - aliceProxy.execute(address(target), data); - } - - modifier whenBatchSizeNotZero() { - _; - } - - function test_BatchCreateWithDurations() external whenBatchSizeNotZero whenDelegateCalled { - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - expectCallToTransferFrom({ - from: users.alice.addr, - to: address(aliceProxy), - amount: defaults.TOTAL_TRANSFER_AMOUNT() - }); - expectMultipleCallsToCreateWithDurations({ count: defaults.BATCH_SIZE(), params: defaults.createWithDurations() }); - expectMultipleCallsToTransferFrom({ - count: defaults.BATCH_SIZE(), - from: address(aliceProxy), - to: address(lockupLinear), - amount: defaults.PER_STREAM_AMOUNT() - }); - - // Assert that the batch of streams has been created successfully. - uint256[] memory actualStreamIds = batchCreateWithDurations(); - uint256[] memory expectedStreamIds = defaults.incrementalStreamIds(); - assertEq(actualStreamIds, expectedStreamIds, "stream ids mismatch"); - } -} diff --git a/test/integration/target/batch-create-with-durations/batchCreateWithDurations.tree b/test/integration/target/batch-create-with-durations/batchCreateWithDurations.tree deleted file mode 100644 index 55be4c22..00000000 --- a/test/integration/target/batch-create-with-durations/batchCreateWithDurations.tree +++ /dev/null @@ -1,9 +0,0 @@ -batchCreateWithDurations.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the batch size is zero - │ └── it should revert - └── when the batch size is not zero - ├── it should create a batch of streams with durations - └── it should perform the ERC-20 transfers diff --git a/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.t.sol b/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.t.sol deleted file mode 100644 index a02d1a42..00000000 --- a/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.t.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { Errors } from "src/libraries/Errors.sol"; -import { Batch } from "src/types/DataTypes.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract BatchCreateWithMilestones_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - Batch.CreateWithMilestones[] memory batchParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.batchCreateWithMilestones({ - lockupDynamic: lockupDynamic, - asset: asset, - batch: batchParams, - transferData: bytes("") - }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_RevertWhen_BatchSizeZero() external whenDelegateCalled { - Batch.CreateWithMilestones[] memory batchParams = new Batch.CreateWithMilestones[](0); - bytes memory data = - abi.encodeCall(target.batchCreateWithMilestones, (lockupDynamic, asset, batchParams, bytes(""))); - vm.expectRevert(Errors.SablierV2ProxyTarget_BatchSizeZero.selector); - aliceProxy.execute(address(target), data); - } - - modifier whenBatchSizeNotZero() { - _; - } - - function test_BatchCreateWithMilestones() external whenBatchSizeNotZero whenDelegateCalled { - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - expectCallToTransferFrom({ - from: users.alice.addr, - to: address(aliceProxy), - amount: defaults.TOTAL_TRANSFER_AMOUNT() - }); - expectMultipleCallsToCreateWithMilestones({ - count: defaults.BATCH_SIZE(), - params: defaults.createWithMilestones() - }); - expectMultipleCallsToTransferFrom({ - count: defaults.BATCH_SIZE(), - from: address(aliceProxy), - to: address(lockupDynamic), - amount: defaults.PER_STREAM_AMOUNT() - }); - - // Assert that the batch of streams has been created successfully. - uint256[] memory actualStreamIds = batchCreateWithMilestones(); - uint256[] memory expectedStreamIds = defaults.incrementalStreamIds(); - assertEq(actualStreamIds, expectedStreamIds, "stream ids mismatch"); - } -} diff --git a/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.tree b/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.tree deleted file mode 100644 index bd4b2cd9..00000000 --- a/test/integration/target/batch-create-with-milestones/batchCreateWithMilestones.tree +++ /dev/null @@ -1,9 +0,0 @@ -batchCreateWithMilestones.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the batch size is zero - │ └── it should revert - └── when the batch size is not zero - ├── it should create a batch of streams with milestones - └── it should perform the ERC-20 transfers diff --git a/test/integration/target/batch-create-with-range/batchCreateWithRange.t.sol b/test/integration/target/batch-create-with-range/batchCreateWithRange.t.sol deleted file mode 100644 index a58170f9..00000000 --- a/test/integration/target/batch-create-with-range/batchCreateWithRange.t.sol +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { Errors } from "src/libraries/Errors.sol"; -import { Batch } from "src/types/DataTypes.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract BatchCreateWithRange_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - Batch.CreateWithRange[] memory batchParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.batchCreateWithRange({ - lockupLinear: lockupLinear, - asset: asset, - batch: batchParams, - transferData: bytes("") - }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_RevertWhen_BatchSizeZero() external whenDelegateCalled { - Batch.CreateWithRange[] memory batchParams = new Batch.CreateWithRange[](0); - bytes memory data = abi.encodeCall(target.batchCreateWithRange, (lockupLinear, asset, batchParams, bytes(""))); - vm.expectRevert(Errors.SablierV2ProxyTarget_BatchSizeZero.selector); - aliceProxy.execute(address(target), data); - } - - modifier whenBatchSizeNotZero() { - _; - } - - function test_BatchCreateWithRange() external whenBatchSizeNotZero whenDelegateCalled { - // Asset flow: proxy owner → proxy → Sablier - // Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract. - expectCallToTransferFrom({ - from: users.alice.addr, - to: address(aliceProxy), - amount: defaults.TOTAL_TRANSFER_AMOUNT() - }); - expectMultipleCallsToCreateWithRange({ count: defaults.BATCH_SIZE(), params: defaults.createWithRange() }); - expectMultipleCallsToTransferFrom({ - count: defaults.BATCH_SIZE(), - from: address(aliceProxy), - to: address(lockupLinear), - amount: defaults.PER_STREAM_AMOUNT() - }); - - // Assert that the batch of streams has been created successfully. - uint256[] memory actualStreamIds = batchCreateWithRange(); - uint256[] memory expectedStreamIds = defaults.incrementalStreamIds(); - assertEq(actualStreamIds, expectedStreamIds, "stream ids mismatch"); - } -} diff --git a/test/integration/target/batch-create-with-range/batchCreateWithRange.tree b/test/integration/target/batch-create-with-range/batchCreateWithRange.tree deleted file mode 100644 index 5d19af97..00000000 --- a/test/integration/target/batch-create-with-range/batchCreateWithRange.tree +++ /dev/null @@ -1,9 +0,0 @@ -batchCreateWithRange.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the batch size is zero - │ └── it should revert - └── when the batch size is not zero - ├── it should create a batch of streams with range - └── it should perform the ERC-20 transfers diff --git a/test/integration/target/burn/burn.t.sol b/test/integration/target/burn/burn.t.sol deleted file mode 100644 index 81361944..00000000 --- a/test/integration/target/burn/burn.t.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract Burn_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.burn({ lockup: lockupLinear, streamId: 0 }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_Burn_LockupDynamic() external whenDelegateCalled { - LockupDynamic.CreateWithMilestones memory params = defaults.createWithMilestones(); - params.recipient = address(aliceProxy); - uint256 streamId = createWithMilestones(params); - test_Burn(lockupDynamic, streamId); - } - - function test_Burn_LockupLinear() external whenDelegateCalled { - LockupLinear.CreateWithRange memory params = defaults.createWithRange(); - params.recipient = address(aliceProxy); - uint256 streamId = createWithRange(params); - test_Burn(lockupLinear, streamId); - } - - function test_Burn(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.END_TIME()); - - // Make the withdrawal. - bytes memory data = abi.encodeCall(target.withdrawMax, (lockup, streamId, address(aliceProxy))); - aliceProxy.execute(address(target), data); - - // Burn the stream. - data = abi.encodeCall(target.burn, (lockup, streamId)); - aliceProxy.execute(address(target), data); - - // Expect the NFT owner to not exist anymore. - vm.expectRevert("ERC721: invalid token ID"); - lockup.getRecipient(streamId); - } -} diff --git a/test/integration/target/burn/burn.tree b/test/integration/target/burn/burn.tree deleted file mode 100644 index fa3934ca..00000000 --- a/test/integration/target/burn/burn.tree +++ /dev/null @@ -1,5 +0,0 @@ -burn.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should burn the stream diff --git a/test/integration/target/cancel-and-create/cancelAndCreate.t.sol b/test/integration/target/cancel-and-create/cancelAndCreate.t.sol deleted file mode 100644 index 68414f0a..00000000 --- a/test/integration/target/cancel-and-create/cancelAndCreate.t.sol +++ /dev/null @@ -1,320 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { ISablierV2LockupDynamic } from "@sablier/v2-core/src/interfaces/ISablierV2LockupDynamic.sol"; -import { ISablierV2LockupLinear } from "@sablier/v2-core/src/interfaces/ISablierV2LockupLinear.sol"; -import { LockupLinear, LockupDynamic } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -/// @dev This contracts tests the following functions: -/// - `cancelAndCreateWithDeltas` -/// - `cancelAndCreateWithDurations` -/// - `cancelAndCreateWithMilestones` -/// - `cancelAndCreateWithRange` -abstract contract CancelAndCreate_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - modifier whenDelegateCalled() { - _; - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH DELTAS - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_CancelAndCreateWithDeltas_NotDelegateCalled() external { - LockupDynamic.CreateWithDeltas memory createParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancelAndCreateWithDeltas({ - lockup: lockupDynamic, - streamId: 0, - lockupDynamic: lockupDynamic, - createParams: createParams, - transferData: bytes("") - }); - } - - function test_CancelAndCreateWithDeltas_SameSablierContract() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithDeltas(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupDynamic; - ISablierV2LockupDynamic createContract = lockupDynamic; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithDeltas({ params: defaults.createWithDeltas() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithDeltas, - ( - cancelContract, - streamId, - createContract, - defaults.createWithDeltas(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - function test_CancelAndCreateWithDeltas_AcrossSablierContracts() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithRange(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupLinear; - ISablierV2LockupDynamic createContract = lockupDynamic; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithDeltas({ params: defaults.createWithDeltas() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithDeltas, - ( - cancelContract, - streamId, - createContract, - defaults.createWithDeltas(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH DURATIONS - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_CancelAndCreateWithDurations_NotDelegateCalled() external { - LockupLinear.CreateWithDurations memory createParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancelAndCreateWithDurations({ - lockup: lockupLinear, - streamId: 0, - lockupLinear: lockupLinear, - createParams: createParams, - transferData: bytes("") - }); - } - - function test_CancelAndCreateWithDurations_SameSablierContract() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithDurations(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupLinear; - ISablierV2LockupLinear createContract = lockupLinear; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithDurations({ params: defaults.createWithDurations() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithDurations, - ( - cancelContract, - streamId, - createContract, - defaults.createWithDurations(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - function test_CancelAndCreateWithDurations_AcrossSablierContracts() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithMilestones(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupDynamic; - ISablierV2LockupLinear createContract = lockupLinear; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithDurations({ params: defaults.createWithDurations() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithDurations, - ( - cancelContract, - streamId, - createContract, - defaults.createWithDurations(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH MILESTONES - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_CancelAndCreateWithMilestones_NotDelegateCalled() external { - LockupDynamic.CreateWithMilestones memory createParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancelAndCreateWithMilestones({ - lockup: lockupDynamic, - streamId: 0, - lockupDynamic: lockupDynamic, - createParams: createParams, - transferData: bytes("") - }); - } - - function test_CancelAndCreateWithMilestones_SameSablierContract() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithMilestones(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupDynamic; - ISablierV2LockupDynamic createContract = lockupDynamic; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithMilestones({ params: defaults.createWithMilestones() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithMilestones, - ( - cancelContract, - streamId, - createContract, - defaults.createWithMilestones(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - function test_CancelAndCreateWithMilestones_AcrossSablierContracts() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithRange(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupLinear; - ISablierV2LockupDynamic createContract = lockupDynamic; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithMilestones({ params: defaults.createWithMilestones() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithMilestones, - ( - cancelContract, - streamId, - createContract, - defaults.createWithMilestones(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH RANGE - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_CancelAndCreateWithRange_NotDelegateCalled() external { - LockupLinear.CreateWithRange memory createParams; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancelAndCreateWithRange({ - lockup: lockupLinear, - streamId: 0, - lockupLinear: lockupLinear, - createParams: createParams, - transferData: bytes("") - }); - } - - function test_CancelAndCreateWithRange_SameSablierContract() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithRange(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupLinear; - ISablierV2LockupLinear createContract = lockupLinear; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithRange({ params: defaults.createWithRange() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithRange, - ( - cancelContract, - streamId, - createContract, - defaults.createWithRange(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } - - function test_CancelAndCreateWithRange_AcrossSablierContracts() external whenDelegateCalled { - // Create the stream due to be canceled. - uint256 streamId = createWithMilestones(); - - // Expect the correct calls to be made. - ISablierV2Lockup cancelContract = lockupDynamic; - ISablierV2LockupLinear createContract = lockupLinear; - expectCallsToCancelAndTransfer(cancelContract, createContract, streamId); - expectCallToCreateWithRange({ params: defaults.createWithRange() }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = abi.encodeCall( - target.cancelAndCreateWithRange, - ( - cancelContract, - streamId, - createContract, - defaults.createWithRange(), - getTransferData(defaults.PER_STREAM_AMOUNT()) - ) - ); - bytes memory response = aliceProxy.execute(address(target), data); - - // Assert that the new stream has been created successfully. - uint256 actualNewStreamId = abi.decode(response, (uint256)); - uint256 expectedNewStreamId = createContract.nextStreamId() - 1; - assertEq(actualNewStreamId, expectedNewStreamId, "new stream id mismatch"); - } -} diff --git a/test/integration/target/cancel-and-create/cancelAndCreate.tree b/test/integration/target/cancel-and-create/cancelAndCreate.tree deleted file mode 100644 index c4540d61..00000000 --- a/test/integration/target/cancel-and-create/cancelAndCreate.tree +++ /dev/null @@ -1,5 +0,0 @@ -cancelAndCreate.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should cancel the stream and create a new one diff --git a/test/integration/target/cancel-multiple/cancelMultiple.t.sol b/test/integration/target/cancel-multiple/cancelMultiple.t.sol deleted file mode 100644 index bc4dd1b6..00000000 --- a/test/integration/target/cancel-multiple/cancelMultiple.t.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { Lockup } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract CancelMultiple_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - IERC20[] memory assets; - uint256[] memory streamIds; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancelMultiple(lockupLinear, assets, streamIds); - } - - modifier whenDelegateCalled() { - _; - } - - function test_CancelMultiple_LockupDynamic() external whenDelegateCalled { - uint256[] memory streamIds = batchCreateWithMilestones(); - test_CancelMultiple(lockupDynamic, streamIds); - } - - function test_CancelMultiple_LockupLinear() external whenDelegateCalled { - uint256[] memory streamIds = batchCreateWithRange(); - test_CancelMultiple(lockupLinear, streamIds); - } - - function test_CancelMultiple(ISablierV2Lockup lockup, uint256[] memory streamIds) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - // Asset flow: Sablier → proxy → proxy owner - expectMultipleCallsToTransfer({ - count: defaults.BATCH_SIZE(), - to: address(aliceProxy), - amount: defaults.REFUND_AMOUNT() - }); - expectCallToTransfer({ to: users.alice.addr, amount: defaults.REFUND_AMOUNT() * defaults.BATCH_SIZE() }); - - bytes memory data = abi.encodeCall(target.cancelMultiple, (lockup, defaults.assets(), streamIds)); - aliceProxy.execute(address(target), data); - - // Assert that all streams have been canceled. - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) { - Lockup.Status actualStatus = lockup.statusOf(streamIds[i]); - assertEq(actualStatus, expectedStatus, "stream status not canceled"); - } - } -} diff --git a/test/integration/target/cancel-multiple/cancelMultiple.tree b/test/integration/target/cancel-multiple/cancelMultiple.tree deleted file mode 100644 index 0934cdf3..00000000 --- a/test/integration/target/cancel-multiple/cancelMultiple.tree +++ /dev/null @@ -1,5 +0,0 @@ -cancelMultiple.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should cancel multiple streams diff --git a/test/integration/target/cancel/cancel.t.sol b/test/integration/target/cancel/cancel.t.sol deleted file mode 100644 index 6f556a7e..00000000 --- a/test/integration/target/cancel/cancel.t.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { Lockup } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract Cancel_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.cancel({ lockup: lockupLinear, streamId: 0 }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_Cancel_LockupDynamic() external whenDelegateCalled { - uint256 streamId = createWithMilestones(); - test_Cancel(lockupDynamic, streamId); - } - - function test_Cancel_LockupLinear() external whenDelegateCalled { - uint256 streamId = createWithRange(); - test_Cancel(lockupLinear, streamId); - } - - function test_Cancel(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - // Asset flow: Sablier → proxy → proxy owner - expectCallToTransfer({ to: address(aliceProxy), amount: defaults.REFUND_AMOUNT() }); - expectCallToTransfer({ to: users.alice.addr, amount: defaults.REFUND_AMOUNT() }); - - // Cancel the stream. - bytes memory data = abi.encodeCall(target.cancel, (lockup, streamId)); - aliceProxy.execute(address(target), data); - - // Assert that the stream has been canceled. - Lockup.Status expectedStatus = Lockup.Status.CANCELED; - Lockup.Status actualStatus = lockup.statusOf(streamId); - assertEq(actualStatus, expectedStatus, "stream not canceled"); - } -} diff --git a/test/integration/target/cancel/cancel.tree b/test/integration/target/cancel/cancel.tree deleted file mode 100644 index f8e1aa6d..00000000 --- a/test/integration/target/cancel/cancel.tree +++ /dev/null @@ -1,5 +0,0 @@ -cancel.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should cancel the stream diff --git a/test/integration/target/renounce/renounce.t.sol b/test/integration/target/renounce/renounce.t.sol deleted file mode 100644 index f3c54d69..00000000 --- a/test/integration/target/renounce/renounce.t.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract Renounce_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.renounce({ lockup: lockupLinear, streamId: 0 }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_Renounce_LockupDynamic() external whenDelegateCalled { - uint256 streamId = createWithMilestones(); - test_Renounce(lockupDynamic, streamId); - } - - function test_Renounce_LockupLinear() external whenDelegateCalled { - uint256 streamId = createWithRange(); - test_Renounce(lockupLinear, streamId); - } - - function test_Renounce(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - // Load the initial state. - bool initialIsCancelable = lockup.isCancelable(streamId); - assertTrue(initialIsCancelable, "stream renounced already"); - - // Renounce the stream. - bytes memory data = abi.encodeCall(target.renounce, (lockup, streamId)); - aliceProxy.execute(address(target), data); - - // Assert that the stream has been renounced. - bool finalIsCancelable = lockup.isCancelable(streamId); - assertFalse(finalIsCancelable, "stream not renounced"); - } -} diff --git a/test/integration/target/renounce/renounce.tree b/test/integration/target/renounce/renounce.tree deleted file mode 100644 index 77d121ec..00000000 --- a/test/integration/target/renounce/renounce.tree +++ /dev/null @@ -1,5 +0,0 @@ -renounce.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should renounce the stream diff --git a/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol b/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol deleted file mode 100644 index 37201d2a..00000000 --- a/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.t.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract WithdrawMaxAndTransfer_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.withdrawMaxAndTransfer({ lockup: lockupLinear, streamId: 0, newRecipient: users.recipient0.addr }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_WithdrawMaxAndTransfer_LockupDynamic() external whenDelegateCalled { - LockupDynamic.CreateWithMilestones memory params = defaults.createWithMilestones(); - params.recipient = address(aliceProxy); - uint256 streamId = createWithMilestones(params); - test_WithdrawMaxAndTransfer(lockupDynamic, streamId); - } - - function test_WithdrawMaxAndTransfer_LockupLinear() external whenDelegateCalled { - LockupLinear.CreateWithRange memory params = defaults.createWithRange(); - params.recipient = address(aliceProxy); - uint256 streamId = createWithRange(params); - test_WithdrawMaxAndTransfer(lockupLinear, streamId); - } - - function test_WithdrawMaxAndTransfer(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - // Asset flow: Sablier → recipient - expectCallToTransfer({ to: address(aliceProxy), amount: defaults.WITHDRAW_AMOUNT() }); - - // Make the max withdrawal and transfer the NFT. - bytes memory data = abi.encodeCall(target.withdrawMaxAndTransfer, (lockup, streamId, users.recipient0.addr)); - aliceProxy.execute(address(target), data); - - // Assert that the withdrawn amount has been updated. - uint128 actualWithdrawnAmount = lockup.getWithdrawnAmount(streamId); - uint128 expectedWithdrawnAmount = defaults.WITHDRAW_AMOUNT(); - assertEq(actualWithdrawnAmount, expectedWithdrawnAmount, "withdrawnAmount"); - - // Assert that the NFT has been transfered. - address actualOwner = lockup.ownerOf(streamId); - address expectedOwner = users.recipient0.addr; - assertEq(actualOwner, expectedOwner, "owner"); - } -} diff --git a/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.tree b/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.tree deleted file mode 100644 index 8c56c2f1..00000000 --- a/test/integration/target/withdraw-max-and-transfer/withdrawMaxAndTransfer.tree +++ /dev/null @@ -1,6 +0,0 @@ -withdrawMaxAndTransfer.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── it should make the max withdrawal - └── it should transfer the NFT diff --git a/test/integration/target/withdraw-max/withdrawMax.t.sol b/test/integration/target/withdraw-max/withdrawMax.t.sol deleted file mode 100644 index d77aadfb..00000000 --- a/test/integration/target/withdraw-max/withdrawMax.t.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract WithdrawMax_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.withdrawMax({ lockup: lockupLinear, streamId: 0, to: users.recipient0.addr }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_WithdrawMax_LockupDynamic() external whenDelegateCalled { - uint256 streamId = createWithMilestones(); - test_WithdrawMax(lockupDynamic, streamId); - } - - function test_WithdrawMax_Linear() external whenDelegateCalled { - uint256 streamId = createWithRange(); - test_WithdrawMax(lockupLinear, streamId); - } - - function test_WithdrawMax(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.END_TIME()); - - // Asset flow: Sablier → recipient - expectCallToTransfer({ to: users.recipient0.addr, amount: defaults.PER_STREAM_AMOUNT() }); - - // Withdraw all assets from the stream. - bytes memory data = abi.encodeCall(target.withdrawMax, (lockup, streamId, users.recipient0.addr)); - aliceProxy.execute(address(target), data); - - // Assert that the withdrawn amount has been updated. - uint128 actualWithdrawnAmount = lockup.getWithdrawnAmount(streamId); - uint128 expectedWithdrawnAmount = defaults.PER_STREAM_AMOUNT(); - assertEq(actualWithdrawnAmount, expectedWithdrawnAmount, "withdrawnAmount"); - } -} diff --git a/test/integration/target/withdraw-max/withdrawMax.tree b/test/integration/target/withdraw-max/withdrawMax.tree deleted file mode 100644 index 0bf3f9b6..00000000 --- a/test/integration/target/withdraw-max/withdrawMax.tree +++ /dev/null @@ -1,5 +0,0 @@ -withdrawMax.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should withdraw all assets from the stream diff --git a/test/integration/target/withdraw-multiple/withdrawMultiple.t.sol b/test/integration/target/withdraw-multiple/withdrawMultiple.t.sol deleted file mode 100644 index 4bf81975..00000000 --- a/test/integration/target/withdraw-multiple/withdrawMultiple.t.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract WithdrawMultiple_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - uint256[] memory streamIds; - uint128[] memory amounts; - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.withdrawMultiple(lockupLinear, streamIds, users.recipient0.addr, amounts); - } - - modifier whenDelegateCalled() { - _; - } - - function test_WithdrawMultiple_LockupDynamic() external whenDelegateCalled { - uint256[] memory streamIds = batchCreateWithMilestones(); - test_WithdrawMultiple(lockupDynamic, streamIds); - } - - function test_WithdrawMultiple_LockupLinear() external whenDelegateCalled { - uint256[] memory streamIds = batchCreateWithRange(); - test_WithdrawMultiple(lockupLinear, streamIds); - } - - function test_WithdrawMultiple(ISablierV2Lockup lockup, uint256[] memory streamIds) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - uint40 batchSize = uint40(defaults.BATCH_SIZE()); - uint128 withdrawAmount = defaults.WITHDRAW_AMOUNT(); - - // Asset flow: Sablier → recipient - expectMultipleCallsToTransfer({ count: batchSize, to: users.recipient0.addr, amount: withdrawAmount }); - - uint128[] memory amounts = new uint128[](batchSize); - for (uint256 i = 0; i < batchSize; ++i) { - amounts[i] = withdrawAmount; - } - - bytes memory data = abi.encodeCall(target.withdrawMultiple, (lockup, streamIds, users.recipient0.addr, amounts)); - aliceProxy.execute(address(target), data); - - // Assert that the withdrawn amount has been updated for all streams. - for (uint256 i = 0; i < batchSize; ++i) { - assertEq(lockup.getWithdrawnAmount(streamIds[i]), withdrawAmount, "withdrawnAmount"); - } - } -} diff --git a/test/integration/target/withdraw-multiple/withdrawMultiple.tree b/test/integration/target/withdraw-multiple/withdrawMultiple.tree deleted file mode 100644 index bb362967..00000000 --- a/test/integration/target/withdraw-multiple/withdrawMultiple.tree +++ /dev/null @@ -1,5 +0,0 @@ -withdrawMultiple.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should withdraw from multiple streams diff --git a/test/integration/target/withdraw/withdraw.t.sol b/test/integration/target/withdraw/withdraw.t.sol deleted file mode 100644 index 58d99203..00000000 --- a/test/integration/target/withdraw/withdraw.t.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { ISablierV2Lockup } from "@sablier/v2-core/src/interfaces/ISablierV2Lockup.sol"; - -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -abstract contract Withdraw_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - function test_RevertWhen_NotDelegateCalled() external { - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.withdraw({ lockup: lockupLinear, streamId: 0, to: users.recipient0.addr, amount: 0 }); - } - - modifier whenDelegateCalled() { - _; - } - - function test_Withdraw_LockupDynamic() external whenDelegateCalled { - uint256 streamId = createWithMilestones(); - test_Withdraw(lockupDynamic, streamId); - } - - function test_Withdraw_LockupLinear() external whenDelegateCalled { - uint256 streamId = createWithRange(); - test_Withdraw(lockupLinear, streamId); - } - - function test_Withdraw(ISablierV2Lockup lockup, uint256 streamId) internal { - // Simulate the passage of time. - vm.warp(defaults.CLIFF_TIME()); - - // Asset flow: Sablier → recipient - expectCallToTransfer({ to: users.recipient0.addr, amount: defaults.WITHDRAW_AMOUNT() }); - - // Withdraw from the stream. - bytes memory data = - abi.encodeCall(target.withdraw, (lockup, streamId, users.recipient0.addr, defaults.WITHDRAW_AMOUNT())); - aliceProxy.execute(address(target), data); - - // Assert that the withdrawn amount has been updated. - uint128 actualWithdrawnAmount = lockup.getWithdrawnAmount(streamId); - uint128 expectedWithdrawnAmount = defaults.WITHDRAW_AMOUNT(); - assertEq(actualWithdrawnAmount, expectedWithdrawnAmount, "withdrawnAmount"); - } -} diff --git a/test/integration/target/withdraw/withdraw.tree b/test/integration/target/withdraw/withdraw.tree deleted file mode 100644 index df272854..00000000 --- a/test/integration/target/withdraw/withdraw.tree +++ /dev/null @@ -1,5 +0,0 @@ -withdraw.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - └── it should withdraw from the stream diff --git a/test/integration/target/wrap-and-create/wrapAndCreate.t.sol b/test/integration/target/wrap-and-create/wrapAndCreate.t.sol deleted file mode 100644 index 891abaaf..00000000 --- a/test/integration/target/wrap-and-create/wrapAndCreate.t.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.19 <0.9.0; - -import { LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; - -import { IWrappedNativeAsset } from "src/interfaces/IWrappedNativeAsset.sol"; -import { Errors } from "src/libraries/Errors.sol"; - -import { Target_Integration_Test } from "../Target.t.sol"; - -/// @dev This contracts tests the following functions: -/// - `wrapAndCreateWithDeltas` -/// - `wrapAndCreateWithDurations` -/// - `wrapAndCreateWithMilestones` -/// - `wrapAndCreateWithRange` -abstract contract WrapAndCreate_Integration_Test is Target_Integration_Test { - function setUp() public virtual override { } - - modifier whenDelegateCalled() { - _; - } - - modifier whenCreditAmountEqualToMsgValue() { - _; - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH DELTAS - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_WrapAndCreateWithDeltas_NotDelegateCalled() external { - LockupDynamic.CreateWithDeltas memory createParams = defaults.createWithDeltas(weth); - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.wrapAndCreateWithDeltas(lockupDynamic, createParams); - } - - function test_RevertWhen_WrapAndCreateWithDeltas_CreditAmountNotEqualToMsgValue() external whenDelegateCalled { - uint256 msgValue = defaults.ETHER_AMOUNT(); - LockupDynamic.CreateWithDeltas memory createParams = defaults.createWithDeltas(wlc); - vm.expectRevert( - abi.encodeWithSelector( - Errors.SablierV2ProxyTarget_CreditAmountMismatch.selector, msgValue, msgValue - 1 wei - ) - ); - bytes memory data = abi.encodeCall(target.wrapAndCreateWithDeltas, (lockupDynamic, createParams)); - aliceProxy.execute{ value: msgValue }(address(target), data); - } - - function test_WrapAndCreateWithDeltas() external whenDelegateCalled whenCreditAmountEqualToMsgValue { - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupDynamic), - amount: defaults.ETHER_AMOUNT() - }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = - abi.encodeCall(target.wrapAndCreateWithDeltas, (lockupDynamic, defaults.createWithDeltas(weth))); - bytes memory response = aliceProxy.execute{ value: defaults.ETHER_AMOUNT() }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupDynamic.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH DURATIONS - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_WrapAndCreateWithDurations_NotDelegateCalled() external { - LockupLinear.CreateWithDurations memory createParams = defaults.createWithDurations(weth); - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.wrapAndCreateWithDurations(lockupLinear, createParams); - } - - function test_RevertWhen_WrapAndCreateWithDurations_CreditAmountNotEqualToMsgValue() external whenDelegateCalled { - uint256 msgValue = defaults.ETHER_AMOUNT(); - LockupLinear.CreateWithDurations memory createParams = defaults.createWithDurations(wlc); - vm.expectRevert( - abi.encodeWithSelector( - Errors.SablierV2ProxyTarget_CreditAmountMismatch.selector, msgValue, msgValue - 1 wei - ) - ); - bytes memory data = abi.encodeCall(target.wrapAndCreateWithDurations, (lockupLinear, createParams)); - aliceProxy.execute{ value: msgValue }(address(target), data); - } - - function test_WrapAndCreateWithDurations() external whenDelegateCalled whenCreditAmountEqualToMsgValue { - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupLinear), - amount: defaults.ETHER_AMOUNT() - }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = - abi.encodeCall(target.wrapAndCreateWithDurations, (lockupLinear, defaults.createWithDurations(weth))); - bytes memory response = aliceProxy.execute{ value: defaults.ETHER_AMOUNT() }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupLinear.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } - - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH MILESTONES - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_WrapAndCreateWithMilestones_NotDelegateCalled() external { - LockupDynamic.CreateWithMilestones memory createParams = defaults.createWithMilestones(weth); - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.wrapAndCreateWithMilestones(lockupDynamic, createParams); - } - - function test_RevertWhen_WrapAndCreateWithMilestones_CreditAmountNotEqualToMsgValue() external whenDelegateCalled { - uint256 msgValue = defaults.ETHER_AMOUNT(); - LockupDynamic.CreateWithMilestones memory createParams = defaults.createWithMilestones(wlc); - vm.expectRevert( - abi.encodeWithSelector( - Errors.SablierV2ProxyTarget_CreditAmountMismatch.selector, msgValue, msgValue - 1 wei - ) - ); - bytes memory data = abi.encodeCall(target.wrapAndCreateWithMilestones, (lockupDynamic, createParams)); - aliceProxy.execute{ value: msgValue }(address(target), data); - } - - function test_WrapAndCreateWithMilestones() external whenDelegateCalled whenCreditAmountEqualToMsgValue { - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupDynamic), - amount: defaults.ETHER_AMOUNT() - }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = - abi.encodeCall(target.wrapAndCreateWithMilestones, (lockupDynamic, defaults.createWithMilestones(weth))); - bytes memory response = aliceProxy.execute{ value: defaults.ETHER_AMOUNT() }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupDynamic.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } - /*////////////////////////////////////////////////////////////////////////// - CREATE WITH RANGE - //////////////////////////////////////////////////////////////////////////*/ - - function test_RevertWhen_WrapAndCreateWithRange_NotDelegateCalled() external { - LockupLinear.CreateWithDurations memory createParams = defaults.createWithDurations(weth); - vm.expectRevert(Errors.CallNotDelegateCall.selector); - target.wrapAndCreateWithDurations(lockupLinear, createParams); - } - - function test_RevertWhen_WrapAndCreateWithRange_CreditAmountNotEqualToMsgValue() external whenDelegateCalled { - uint256 msgValue = defaults.ETHER_AMOUNT(); - LockupLinear.CreateWithRange memory createParams = defaults.createWithRange(wlc); - vm.expectRevert( - abi.encodeWithSelector( - Errors.SablierV2ProxyTarget_CreditAmountMismatch.selector, msgValue, msgValue - 1 wei - ) - ); - bytes memory data = abi.encodeCall(target.wrapAndCreateWithRange, (lockupLinear, createParams)); - aliceProxy.execute{ value: msgValue }(address(target), data); - } - - function test_WrapAndCreateWithRange() external whenDelegateCalled whenCreditAmountEqualToMsgValue { - // Expect the correct calls to be made. - vm.expectCall(address(weth), abi.encodeCall(IWrappedNativeAsset.deposit, ())); - expectCallToTransferFrom({ - asset_: address(weth), - from: address(aliceProxy), - to: address(lockupLinear), - amount: defaults.ETHER_AMOUNT() - }); - - // ABI encode the parameters and call the function via the proxy. - bytes memory data = - abi.encodeCall(target.wrapAndCreateWithRange, (lockupLinear, defaults.createWithRange(weth))); - bytes memory response = aliceProxy.execute{ value: defaults.ETHER_AMOUNT() }(address(target), data); - - // Assert that the stream has been created successfully. - uint256 actualStreamId = abi.decode(response, (uint256)); - uint256 expectedStreamId = lockupLinear.nextStreamId() - 1; - assertEq(actualStreamId, expectedStreamId, "stream id mismatch"); - } -} diff --git a/test/integration/target/wrap-and-create/wrapAndCreate.tree b/test/integration/target/wrap-and-create/wrapAndCreate.tree deleted file mode 100644 index 51aaf4e6..00000000 --- a/test/integration/target/wrap-and-create/wrapAndCreate.tree +++ /dev/null @@ -1,8 +0,0 @@ -wrapAndCreate.t.sol -├── when not delegate called -│ └── it should revert -└── when delegate called - ├── when the credit amount is not equal to msg.value - │ └── it should revert - └── when the credit amount is equal to msg.value - └── it should wrap the native asset payment and create the stream diff --git a/test/mocks/WETH.sol b/test/mocks/WETH.sol deleted file mode 100644 index b2e86833..00000000 --- a/test/mocks/WETH.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -import { IWrappedNativeAsset } from "../../src/interfaces/IWrappedNativeAsset.sol"; - -contract WETH is IWrappedNativeAsset, ERC20("Wrapped Ether", "WETH") { - receive() external payable virtual { - deposit(); - } - - function deposit() public payable virtual { - _mint({ account: msg.sender, amount: msg.value }); - } - - function withdraw(uint256 amount) public virtual { - _burn({ account: msg.sender, amount: amount }); - payable(msg.sender).transfer(amount); - } -} diff --git a/test/mocks/WLC.sol b/test/mocks/WLC.sol deleted file mode 100644 index 2c6fadd0..00000000 --- a/test/mocks/WLC.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19 <0.9.0; - -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -import { IWrappedNativeAsset } from "../../src/interfaces/IWrappedNativeAsset.sol"; - -contract WLC is IWrappedNativeAsset, ERC20("Wrapped Low Credit", "WLC") { - receive() external payable virtual { - deposit(); - } - - /// @dev Subtracts 1 wei from the deposit amount. - function deposit() public payable virtual { - _mint({ account: msg.sender, amount: msg.value - 1 wei }); - } - - function withdraw(uint256 amount) public virtual { - _burn({ account: msg.sender, amount: amount }); - payable(msg.sender).transfer(amount); - } -} diff --git a/test/utils/Defaults.sol b/test/utils/Defaults.sol index e4d4bd67..eff612d9 100644 --- a/test/utils/Defaults.sol +++ b/test/utils/Defaults.sol @@ -3,14 +3,10 @@ pragma solidity >=0.8.19 <0.9.0; import { Arrays } from "@openzeppelin/contracts/utils/Arrays.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; import { ud2x18, UD60x18 } from "@sablier/v2-core/src/types/Math.sol"; import { Broker, LockupDynamic, LockupLinear } from "@sablier/v2-core/src/types/DataTypes.sol"; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; -import { PermitSignature } from "@uniswap/permit2-test/utils/PermitSignature.sol"; import { Batch } from "src/types/DataTypes.sol"; -import { Permit2Params } from "src/types/Permit2.sol"; import { ArrayBuilder } from "./ArrayBuilder.sol"; import { BatchBuilder } from "./BatchBuilder.sol"; @@ -19,7 +15,7 @@ import { MerkleBuilder } from "./MerkleBuilder.sol"; import { Users } from "./Types.sol"; /// @notice Contract with default values for testing. -contract Defaults is Merkle, PermitSignature { +contract Defaults is Merkle { using MerkleBuilder for uint256[]; /*////////////////////////////////////////////////////////////////////////// @@ -64,19 +60,15 @@ contract Defaults is Merkle, PermitSignature { //////////////////////////////////////////////////////////////////////////*/ IERC20 private asset; - IPRBProxy private proxy; - IAllowanceTransfer private permit2; Users private users; /*////////////////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////////*/ - constructor(Users memory users_, IERC20 asset_, IAllowanceTransfer permit2_, IPRBProxy proxy_) { + constructor(Users memory users_, IERC20 asset_) { users = users_; asset = asset_; - permit2 = permit2_; - proxy = proxy_; // Initialize the immutables. START_TIME = uint40(block.timestamp) + 100 seconds; @@ -85,10 +77,10 @@ contract Defaults is Merkle, PermitSignature { EXPIRATION = uint40(block.timestamp) + 12 weeks; // Initialize the Merkle tree. - LEAVES[0] = MerkleBuilder.computeLeaf(INDEX1, users.recipient1.addr, CLAIM_AMOUNT); - LEAVES[1] = MerkleBuilder.computeLeaf(INDEX2, users.recipient2.addr, CLAIM_AMOUNT); - LEAVES[2] = MerkleBuilder.computeLeaf(INDEX3, users.recipient3.addr, CLAIM_AMOUNT); - LEAVES[3] = MerkleBuilder.computeLeaf(INDEX4, users.recipient4.addr, CLAIM_AMOUNT); + LEAVES[0] = MerkleBuilder.computeLeaf(INDEX1, users.recipient1, CLAIM_AMOUNT); + LEAVES[1] = MerkleBuilder.computeLeaf(INDEX2, users.recipient2, CLAIM_AMOUNT); + LEAVES[2] = MerkleBuilder.computeLeaf(INDEX3, users.recipient3, CLAIM_AMOUNT); + LEAVES[3] = MerkleBuilder.computeLeaf(INDEX4, users.recipient4, CLAIM_AMOUNT); MerkleBuilder.sortLeaves(LEAVES); MERKLE_ROOT = getRoot(LEAVES.toBytes32()); } @@ -98,72 +90,29 @@ contract Defaults is Merkle, PermitSignature { //////////////////////////////////////////////////////////////////////////*/ function index1Proof() public view returns (bytes32[] memory) { - uint256 leaf = MerkleBuilder.computeLeaf(INDEX1, users.recipient1.addr, CLAIM_AMOUNT); + uint256 leaf = MerkleBuilder.computeLeaf(INDEX1, users.recipient1, CLAIM_AMOUNT); uint256 pos = Arrays.findUpperBound(LEAVES, leaf); return getProof(LEAVES.toBytes32(), pos); } function index2Proof() public view returns (bytes32[] memory) { - uint256 leaf = MerkleBuilder.computeLeaf(INDEX2, users.recipient2.addr, CLAIM_AMOUNT); + uint256 leaf = MerkleBuilder.computeLeaf(INDEX2, users.recipient2, CLAIM_AMOUNT); uint256 pos = Arrays.findUpperBound(LEAVES, leaf); return getProof(LEAVES.toBytes32(), pos); } function index3Proof() public view returns (bytes32[] memory) { - uint256 leaf = MerkleBuilder.computeLeaf(INDEX3, users.recipient3.addr, CLAIM_AMOUNT); + uint256 leaf = MerkleBuilder.computeLeaf(INDEX3, users.recipient3, CLAIM_AMOUNT); uint256 pos = Arrays.findUpperBound(LEAVES, leaf); return getProof(LEAVES.toBytes32(), pos); } function index4Proof() public view returns (bytes32[] memory) { - uint256 leaf = MerkleBuilder.computeLeaf(INDEX4, users.recipient4.addr, CLAIM_AMOUNT); + uint256 leaf = MerkleBuilder.computeLeaf(INDEX4, users.recipient4, CLAIM_AMOUNT); uint256 pos = Arrays.findUpperBound(LEAVES, leaf); return getProof(LEAVES.toBytes32(), pos); } - /*////////////////////////////////////////////////////////////////////////// - PERMIT2 - //////////////////////////////////////////////////////////////////////////*/ - - uint48 public constant PERMIT2_EXPIRATION = type(uint48).max; - uint256 public constant PERMIT2_SIG_DEADLINE = type(uint48).max; - - function permit2Params(uint160 amount) public view returns (bytes memory) { - return permit2Params(users.alice.addr, address(proxy), amount, users.alice.key); - } - - function permit2Params( - address user, - address spender, - uint160 amount, - uint256 privateKey - ) - public - view - returns (bytes memory) - { - (,, uint48 nonce) = permit2.allowance({ user: user, token: address(asset), spender: spender }); - IAllowanceTransfer.PermitSingle memory permitSingle = IAllowanceTransfer.PermitSingle({ - details: IAllowanceTransfer.PermitDetails({ - amount: amount, - expiration: PERMIT2_EXPIRATION, - nonce: nonce, - token: address(asset) - }), - sigDeadline: PERMIT2_SIG_DEADLINE, - spender: spender - }); - Permit2Params memory permit2Params_ = Permit2Params({ - permitSingle: permitSingle, - signature: getPermitSignature({ - permit: permitSingle, - privateKey: privateKey, - domainSeparator: permit2.DOMAIN_SEPARATOR() - }) - }); - return abi.encode(permit2Params_); - } - /*////////////////////////////////////////////////////////////////////////// SABLIER-V2-LOCKUP //////////////////////////////////////////////////////////////////////////*/ @@ -174,7 +123,7 @@ contract Defaults is Merkle, PermitSignature { } function broker() public view returns (Broker memory) { - return Broker({ account: users.broker.addr, fee: BROKER_FEE }); + return Broker({ account: users.broker, fee: BROKER_FEE }); } function incrementalStreamIds() public pure returns (uint256[] memory streamIds) { @@ -194,9 +143,9 @@ contract Defaults is Merkle, PermitSignature { asset: asset_, broker: broker(), cancelable: true, - recipient: users.recipient0.addr, + recipient: users.recipient0, segments: segmentsWithDeltas(), - sender: address(proxy), + sender: users.alice, totalAmount: PER_STREAM_AMOUNT, transferable: true }); @@ -211,9 +160,9 @@ contract Defaults is Merkle, PermitSignature { asset: asset_, broker: broker(), cancelable: true, - recipient: users.recipient0.addr, + recipient: users.recipient0, segments: segments(), - sender: address(proxy), + sender: users.alice, startTime: START_TIME, totalAmount: PER_STREAM_AMOUNT, transferable: true @@ -274,8 +223,8 @@ contract Defaults is Merkle, PermitSignature { broker: broker(), cancelable: true, durations: durations(), - recipient: users.recipient0.addr, - sender: address(proxy), + recipient: users.recipient0, + sender: users.alice, totalAmount: PER_STREAM_AMOUNT, transferable: true }); @@ -291,8 +240,8 @@ contract Defaults is Merkle, PermitSignature { broker: broker(), cancelable: true, range: linearRange(), - recipient: users.recipient0.addr, - sender: address(proxy), + recipient: users.recipient0, + sender: users.alice, totalAmount: PER_STREAM_AMOUNT, transferable: true }); diff --git a/test/utils/DeployOptimized.sol b/test/utils/DeployOptimized.sol index d2593035..24e5bffb 100644 --- a/test/utils/DeployOptimized.sol +++ b/test/utils/DeployOptimized.sol @@ -1,14 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.19 <0.9.0; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; import { StdCheats } from "forge-std/StdCheats.sol"; import { ISablierV2Batch } from "../../src/interfaces/ISablierV2Batch.sol"; import { ISablierV2MerkleStreamerFactory } from "../../src/interfaces/ISablierV2MerkleStreamerFactory.sol"; -import { SablierV2ProxyTargetApprove } from "../../src/SablierV2ProxyTargetApprove.sol"; -import { SablierV2ProxyTargetPermit2 } from "../../src/SablierV2ProxyTargetPermit2.sol"; -import { SablierV2ProxyTargetPush } from "../../src/SablierV2ProxyTargetPush.sol"; abstract contract DeployOptimized is StdCheats { /// @dev Deploys {SablierV2Batch} from an optimized source compiled with `--via-ir`. @@ -23,55 +19,11 @@ abstract contract DeployOptimized is StdCheats { ); } - /// @dev Deploys {SablierV2ProxyTargetApprove} from an optimized source compiled with `--via-ir`. - function deployOptimizedProxyTargetApprove() internal returns (SablierV2ProxyTargetApprove) { - return SablierV2ProxyTargetApprove( - deployCode("out-optimized/SablierV2ProxyTargetApprove.sol/SablierV2ProxyTargetApprove.json") - ); - } - - /// @dev Deploys {SablierV2ProxyTargetPermit2} from an optimized source compiled with `--via-ir`. - function deployOptimizedProxyTargetPermit2(IAllowanceTransfer permit2_) - internal - returns (SablierV2ProxyTargetPermit2) - { - return SablierV2ProxyTargetPermit2( - deployCode( - "out-optimized/SablierV2ProxyTargetPermit2.sol/SablierV2ProxyTargetPermit2.json", abi.encode(permit2_) - ) - ); - } - - /// @dev Deploys {SablierV2ProxyTargetPush} from an optimized source compiled with `--via-ir`. - function deployOptimizedProxyTargetPush() internal returns (SablierV2ProxyTargetPush) { - return SablierV2ProxyTargetPush( - deployCode("out-optimized/SablierV2ProxyTargetPush.sol/SablierV2ProxyTargetPush.json") - ); - } - /// @notice Deploys all V2 Periphery contracts from a optimized source in the following order: /// /// 1. {SablierV2Batch} /// 2. {SablierV2MerkleStreamerFactory} - /// 3. {SablierV2ProxyTargetApprove} - /// 4. {SablierV2ProxyTargetPermit2} - /// 5. {SablierV2ProxyTargetPush} - function deployOptimizedPeriphery(IAllowanceTransfer permit2_) - internal - returns ( - ISablierV2Batch, - ISablierV2MerkleStreamerFactory, - SablierV2ProxyTargetApprove, - SablierV2ProxyTargetPermit2, - SablierV2ProxyTargetPush - ) - { - return ( - deployOptimizedBatch(), - deployOptimizedMerkleStreamerFactory(), - deployOptimizedProxyTargetApprove(), - deployOptimizedProxyTargetPermit2(permit2_), - deployOptimizedProxyTargetPush() - ); + function deployOptimizedPeriphery() internal returns (ISablierV2Batch, ISablierV2MerkleStreamerFactory) { + return (deployOptimizedBatch(), deployOptimizedMerkleStreamerFactory()); } } diff --git a/test/utils/Precompiles.sol b/test/utils/Precompiles.sol index 1166e54b..9f4d7e52 100644 --- a/test/utils/Precompiles.sol +++ b/test/utils/Precompiles.sol @@ -2,11 +2,8 @@ // solhint-disable max-line-length,no-inline-assembly,reason-string pragma solidity >=0.8.19; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; - import { ISablierV2Batch } from "../../src/interfaces/ISablierV2Batch.sol"; import { ISablierV2MerkleStreamerFactory } from "../../src/interfaces/ISablierV2MerkleStreamerFactory.sol"; -import { ISablierV2ProxyTarget } from "../../src/interfaces/ISablierV2ProxyTarget.sol"; contract Precompiles { /*////////////////////////////////////////////////////////////////////////// @@ -17,12 +14,6 @@ contract Precompiles { hex"6080806040523461001657611a4a908161001c8239f35b600080fdfe608080604052600436101561001357600080fd5b60003560e01c9081638c72706e14610c7d575080639b38b39a14610864578063bd4eb1a4146104ac5763e8d349611461004b57600080fd5b346104345760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610434576100826111c0565b61008a6110c7565b9060443567ffffffffffffffff808211610434573660238301121561043457816004013511610434573660246101208360040135028301011161043457806004013515610482576000805b8260040135821061044d5761010291508473ffffffffffffffffffffffffffffffffffffffff8516611589565b61010f816004013561130a565b9160005b82600401358110610130576040518061012c8682611185565b0390f35b8060e0610145828660040135602488016111e3565b01610163606061015d84886004013560248a016111e3565b01611359565b90610176838760040135602489016111e3565b91610194602061018e868a6004013560248c016111e3565b01611366565b6101ae6101a9868a6004013560248c016111e3565b611366565b916fffffffffffffffffffffffffffffffff6101dd60406101d78960048e013560248f016111e3565b01611223565b73ffffffffffffffffffffffffffffffffffffffff61020c8c61015d60809c8260248f946004013591016111e3565b94816040519761021b89611240565b16875216602086015216604084015273ffffffffffffffffffffffffffffffffffffffff8b166060840152151586830152151560a082015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608436030112610434576103c4926102c060e09360405161029581611279565b6102a160a08501611387565b81526102b060c0809501611387565b6020820152838501523690611399565b83830152604051957fab167ccc00000000000000000000000000000000000000000000000000000000875273ffffffffffffffffffffffffffffffffffffffff835116600488015273ffffffffffffffffffffffffffffffffffffffff60208401511660248801526fffffffffffffffffffffffffffffffff604084015116604488015273ffffffffffffffffffffffffffffffffffffffff60608401511660648801528201511515608487015260a0820151151560a4870152810151602064ffffffffff918281511660c489015201511660e486015201516101048401906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b60208261014481600073ffffffffffffffffffffffffffffffffffffffff88165af1801561044157600090610409575b6001925061040282876113df565b5201610113565b506020823d602011610439575b81610423602093836112b1565b8101031261043457600191516103f4565b600080fd5b3d9150610416565b6040513d6000823e3d90fd5b6001906fffffffffffffffffffffffffffffffff61047860406101d786886004013560248a016111e3565b16019101906100d5565b60046040517f763e559d000000000000000000000000000000000000000000000000000000008152fd5b34610434576104ba366110ea565b909281156104825760009060005b838110610836575073ffffffffffffffffffffffffffffffffffffffff6104f29116918483611589565b6104fb8261130a565b9260005b838110610514576040518061012c8782611185565b61051f818588611404565b60a001908685610530838284611404565b60200161053c90611359565b9381610549858286611404565b60600161055590611366565b85610561818488611404565b60e0810161056e91611444565b9561057a929197611404565b61058390611366565b968c87610591818684611404565b60800161059d90611223565b946105a792611404565b6040016105b390611359565b90604051986105c18a611240565b73ffffffffffffffffffffffffffffffffffffffff168952151560208901521515604088015273ffffffffffffffffffffffffffffffffffffffff1660608701526fffffffffffffffffffffffffffffffff16608086015273ffffffffffffffffffffffffffffffffffffffff861660a08601523661063f91611399565b60c0850152369061064f92611498565b60e083015260405180927f168444560000000000000000000000000000000000000000000000000000000082526004820160209052610144820190805173ffffffffffffffffffffffffffffffffffffffff166024840152602081015115156044840152604081015115156064840152606081015173ffffffffffffffffffffffffffffffffffffffff16608484015260808101516fffffffffffffffffffffffffffffffff1660a484015260a081015173ffffffffffffffffffffffffffffffffffffffff1660c484015260c081015160e4840161074d916020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b60e0015190610124830161012090528151809152610164830191602001906000905b8082106107db57505050908060209203816000885af18015610441576000906107a8575b600192506107a182886113df565b52016104ff565b506020823d6020116107d3575b816107c2602093836112b1565b810103126104345760019151610793565b3d91506107b5565b919350916020606082610828600194885164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b01940192018593929161076f565b916001906fffffffffffffffffffffffffffffffff61085b60806101d787898c611404565b160192016104c8565b346104345760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104345761089b6111c0565b6108a36110c7565b6044359167ffffffffffffffff8084116104345736602385011215610434578360040135116104345760248301903660246101408660040135028601011161043457836004013515610482576000805b85600401358210610c4b5761092091508473ffffffffffffffffffffffffffffffffffffffff8416611589565b61092d846004013561130a565b9260005b8560040135811061094a576040518061012c8782611185565b808661010061095f87948360040135866113f3565b0183610975606061015d868660040135856113f3565b610998602061018e8761098d818960040135886113f3565b9760040135866113f3565b906fffffffffffffffffffffffffffffffff8c73ffffffffffffffffffffffffffffffffffffffff6109fe6109ea60406101d78c6109de6101a98260048a01358e6113f3565b9a8760040135906113f3565b9261015d8b60809d8e9360040135906113f3565b948160405197610a0d89611240565b16875216602086015216604084015273ffffffffffffffffffffffffffffffffffffffff88166060840152151586830152151560a082015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60843603011261043457610bd392610ac260e093604051610a878161125d565b610a9360a08501611387565b8152610ab28660c095610aa7878201611387565b602085015201611387565b6040820152838501523690611399565b83830152604051957f96ce143100000000000000000000000000000000000000000000000000000000875273ffffffffffffffffffffffffffffffffffffffff835116600488015273ffffffffffffffffffffffffffffffffffffffff60208401511660248801526fffffffffffffffffffffffffffffffff604084015116604488015273ffffffffffffffffffffffffffffffffffffffff60608401511660648801528201511515608487015260a0820151151560a4870152810151604064ffffffffff918281511660c48901528260208201511660e489015201511661010486015201516101248401906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b60208261016481600073ffffffffffffffffffffffffffffffffffffffff89165af1801561044157600090610c18575b60019250610c1182886113df565b5201610931565b506020823d602011610c43575b81610c32602093836112b1565b810103126104345760019151610c03565b3d9150610c25565b6001906fffffffffffffffffffffffffffffffff610c7360406101d7868b600401358a6113f3565b16019101906108f3565b3461043457610c8b366110ea565b929093831561109f57506000805b84821061107157610cc291508373ffffffffffffffffffffffffffffffffffffffff8416611589565b610ccb8361130a565b9360005b848110610ce4576040518061012c8882611185565b60c0610cf1828785611549565b0190610d03604061015d838987611549565b91610d14608061018e848a88611549565b92610d2e610d23848a88611549565b610100810190611444565b9091610d3e6101a9868c8a611549565b936020610d4c878d8b611549565b01359464ffffffffff861686036104345788610d7f606061015d8f80610d7960a06101d78f80958a611549565b95611549565b96604051998a61012081011067ffffffffffffffff6101208d0111176110425773ffffffffffffffffffffffffffffffffffffffff908b99610e3a99989764ffffffffff6fffffffffffffffffffffffffffffffff96956101009f86610e2e9b9a61012083016040521690521660208d0152151560408c0152151560608b01521660808901521660a087015273ffffffffffffffffffffffffffffffffffffffff8b1660c08701523690611399565b60e08501523691611498565b838201526040519283917fc33cd35e0000000000000000000000000000000000000000000000000000000083526020600484015273ffffffffffffffffffffffffffffffffffffffff815116602484015264ffffffffff602082015116604484015260408101511515606484015260608101511515608484015273ffffffffffffffffffffffffffffffffffffffff60808201511660a48401526fffffffffffffffffffffffffffffffff60a08201511660c484015273ffffffffffffffffffffffffffffffffffffffff60c08201511660e4840152610f4360e08201516101048501906020809173ffffffffffffffffffffffffffffffffffffffff81511684520151910152565b0151610140610144830152805180610164840152602061018484019201906000905b808210610fe75750505090806020920381600073ffffffffffffffffffffffffffffffffffffffff89165af1801561044157600090610fb4575b60019250610fad82896113df565b5201610ccf565b506020823d602011610fdf575b81610fce602093836112b1565b810103126104345760019151610f9f565b3d9150610fc1565b919350916020606082611034600194885164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b019401920185939291610f65565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6001906fffffffffffffffffffffffffffffffff61109560a06101d7868a8c611549565b1601910190610c99565b807f763e559d0000000000000000000000000000000000000000000000000000000060049252fd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361043457565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126104345773ffffffffffffffffffffffffffffffffffffffff91600435838116810361043457926024359081168103610434579160443567ffffffffffffffff9283821161043457806023830112156104345781600401359384116104345760248460051b83010111610434576024019190565b6020908160408183019282815285518094520193019160005b8281106111ac575050505090565b83518552938101939281019260010161119e565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361043457565b91908110156111f457610120020190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b356fffffffffffffffffffffffffffffffff811681036104345790565b610100810190811067ffffffffffffffff82111761104257604052565b6060810190811067ffffffffffffffff82111761104257604052565b6040810190811067ffffffffffffffff82111761104257604052565b6080810190811067ffffffffffffffff82111761104257604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761104257604052565b67ffffffffffffffff81116110425760051b60200190565b90611314826112f2565b61132160405191826112b1565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061134f82946112f2565b0190602036910137565b3580151581036104345790565b3573ffffffffffffffffffffffffffffffffffffffff811681036104345790565b359064ffffffffff8216820361043457565b9190826040910312610434576040516113b181611279565b8092803573ffffffffffffffffffffffffffffffffffffffff81168103610434578252602090810135910152565b80518210156111f45760209160051b010190565b91908110156111f457610140020190565b91908110156111f45760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0181360301821215610434570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610434570180359067ffffffffffffffff82116104345760200191606082023603831361043457565b9291926114a4826112f2565b6040946114b3865192836112b1565b8195848352602080930191606080960285019481861161043457925b8584106114df5750505050505050565b8684830312610434578251906114f48261125d565b84356fffffffffffffffffffffffffffffffff81168103610434578252858501359067ffffffffffffffff8216820361043457828792838b95015261153a868801611387565b868201528152019301926114cf565b91908110156111f45760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee181360301821215610434570190565b90604080516020907f23b872dd000000000000000000000000000000000000000000000000000000008282015233602482015260449030828201528660648201526064815260a081019080821067ffffffffffffffff831117611042576115f29185528561179d565b73ffffffffffffffffffffffffffffffffffffffff94858516958451917fdd62ed3e0000000000000000000000000000000000000000000000000000000083523060048401521690816024820152838184818a5afa90811561177a57908891600091611747575b5010611669575b50505050505050565b8351956000808589017f095ea7b3000000000000000000000000000000000000000000000000000000009a8b82528560248c0152868b0152858a526116ad8a611295565b89519082855af1906116bd6118bd565b82611714575b5081611709575b50611660576116fd966116f8945193840152602483015260008183015281526116f281611295565b8261179d565b61179d565b38808080808080611660565b90503b1515386116ca565b80919250519085821592831561172f575b50505090386116c3565b61173f9350820181019101611785565b388581611725565b91508482813d8311611773575b61175e81836112b1565b81010312611770575087905138611659565b80fd5b503d611754565b85513d6000823e3d90fd5b90816020910312610434575180151581036104345790565b6040516118089173ffffffffffffffffffffffffffffffffffffffff166117c382611279565b6000806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af16118026118bd565b9161191b565b8051908282159283156118a5575b505050156118215750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b6118b59350820181019101611785565b388281611816565b3d15611916573d9067ffffffffffffffff8211611042576040519161190a60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601846112b1565b82523d6000602084013e565b606090565b91929015611996575081511561192f575090565b3b156119385790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156119a95750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b848110611a26575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b8181018301518682016044015285935082016119e556fea164736f6c6343000815000a"; bytes public constant BYTECODE_MERKLE_STREAMER_FACTORY = hex"6080806040523461001657611d7b908161001c8239f35b600080fdfe600436101561000d57600080fd5b60003560e01c6373b01dbb1461002257600080fd5b3461053b576101807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261053b5773ffffffffffffffffffffffffffffffffffffffff600435166004350361053b5773ffffffffffffffffffffffffffffffffffffffff602435166024350361053b5773ffffffffffffffffffffffffffffffffffffffff604435166044350361053b5764ffffffffff608435166084350361053b5760407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c36011261053b5760c060405260a43564ffffffffff8116810361053b5760805264ffffffffff60c4351660c4350361053b5760c43560a05260e435801515810361053b5761010435801515810361053b5767ffffffffffffffff610124351161053b573660236101243501121561053b5767ffffffffffffffff61012435600401351161050c57604051906101ae60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f610124356004013501160183610540565b600461012435908101358084523691016024011161053b5761012435600401356024610124350160208401376000602061012435600401358401015260405161020f6020820160806020908164ffffffffff91828151168552015116910152565b6040815280606081011067ffffffffffffffff60608301111761050c5760608101604052606060808201917fffffffffffffffffffffffffffffffffffffffff00000000000000000000000080600435841b16845280602435841b166094830152604435831b1660a882015260643560bc8201527fffffffffff00000000000000000000000000000000000000000000000000000060843560d81b1660dc8201526102f56023838380516102ca8160e1840160208501610581565b81018a151560f81b60e182015288151560f81b60e28201520301600381018585015201838301610540565b01519020604051806117ca81011067ffffffffffffffff6117ca8301111761050c576117ca6105a5823973ffffffffffffffffffffffffffffffffffffffff60043581166117ca8301908152602435821660208201526044359091166040820152606435606082015264ffffffffff608435811660808084019190915251811660a080840191909152511660c082015285151560e08201528315156101008201526101209082900301906000f591821561050057602093604051926101409173ffffffffffffffffffffffffffffffffffffffff861685526064358786015264ffffffffff6084351660408601526104056060860160806020908164ffffffffff91828151168552015116910152565b151560a0850152151560c08401528060e0840152815180918401526104338161016093878587019101610581565b61014435610100840152610164356101208401527fb2f6bc588a802f2ce7f8dec57a5096c107d2fc000d5b4cc65745a2c0e232349c73ffffffffffffffffffffffffffffffffffffffff604435169373ffffffffffffffffffffffffffffffffffffffff6024351693817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f73ffffffffffffffffffffffffffffffffffffffff600435169601168101030190a473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b6040513d6000823e3d90fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761050c57604052565b60005b8381106105945750506000910152565b818101518382015260200161058456fe610160604081815234620002e05781620017ca803803809162000023828562000301565b833981010361012091828212620002e05783516001600160a01b038082169391849003620002e057602090818701519481861693848703620002e0578589015192831692838103620002e05760608a015190876200008460808d0162000325565b93609f190112620002e0578751918289016001600160401b03811184821017620002ca578952620000b860a08d0162000325565b8352620000c860c08d0162000325565b83880190815293620000dd60e08e0162000338565b91610100809e01620000ef9062000338565b93600097600160a01b60019003198954161788556080528960e0528d5260c05260a05289526101409788525164ffffffffff16600254915160281b69ffffffffff00000000001691600160501b600190031916171760025584519280840191808063095ea7b360e01b948581528860248901526000196044890152604488526200017988620002e5565b87519082885af16200018a6200044f565b8162000288575b50806200027d575b156200023b575b505050505050519161125d93846200056d853960805184818161037a015281816106400152610c8d015260a0518481816106ee0152610b7c015260c05184818161015001528181610aba01528181610f0d01526110cd015260e05184818161020c015281816105cc0152610c2e01525183818161032b01526105660152518281816107160152610b400152518181816101a001526108850152f35b62000271956200026b9388519384015260248301526044820152604481526200026481620002e5565b8262000346565b62000346565b388080808080620001a0565b50833b151562000199565b80915051838115918215620002a3575b505090503862000191565b8380929350010312620002c65782620002bd910162000338565b80833862000298565b5080fd5b634e487b7160e01b600052604160045260246000fd5b600080fd5b608081019081106001600160401b03821117620002ca57604052565b601f909101601f19168101906001600160401b03821190821017620002ca57604052565b519064ffffffffff82168203620002e057565b51908115158203620002e057565b60408051908101916001600160a01b03166001600160401b03831182841017620002ca57620003ba926040526000806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af1620003b36200044f565b9162000492565b80518281159182156200042c575b5050905015620003d55750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b8380929350010312620002e0578162000446910162000338565b808238620003c8565b3d156200048d573d906001600160401b038211620002ca576040519162000481601f8201601f19166020018462000301565b82523d6000602084013e565b606090565b91929015620004f75750815115620004a8575090565b3b15620004b25790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156200050b5750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b82851062000552575050604492506000838284010152601f80199101168101030190fd5b84810182015186860160440152938101938593506200052e56fe60806040818152600436101561001457600080fd5b600091823560e01c9081631686c90914610ba15750806316c3549d14610b655780631bfd681414610b295780633bfe03a814610afa5780633f31ae3f1461039e5780634800d97f1461034e57806351e75e8b1461031457806375829def14610230578063845aef4b146101e057806390e64d13146101c45780639e93e57714610174578063bb4b573414610133578063ce516507146100f15763f851a440146100bc57600080fd5b346100ed57816003193601126100ed5773ffffffffffffffffffffffffffffffffffffffff60209254169051908152f35b5080fd5b50346100ed5760206003193601126100ed5760209061012a60043560ff6001918060081c60005282602052161b60406000205416151590565b90519015158152f35b50346100ed57816003193601126100ed576020905164ffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100ed57816003193601126100ed576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100ed57816003193601126100ed5760209061012a6110c5565b50346100ed57816003193601126100ed576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5090346103115760206003193601126103115761024b610ff5565b81549073ffffffffffffffffffffffffffffffffffffffff908183163381036102c357507fffffffffffffffffffffffff00000000000000000000000000000000000000009394501691829116178255337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808380a380f35b85517fc6cce6a400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152336024820152604490fd5b80fd5b50346100ed57816003193601126100ed57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346100ed57816003193601126100ed576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b509034610311576080600319360112610311576004359160243573ffffffffffffffffffffffffffffffffffffffff8116809103610af657604435906fffffffffffffffffffffffffffffffff8216809203610af2576064359067ffffffffffffffff95868311610aee5736602384011215610aee5782600401358781116109d5578060051b9360248582010190368211610aea5787516020810190858252868a8201528860608201526060815261045581611068565b5190208851602081019182526020815261046e8161101d565b5190209261047a6110c5565b610a8d576104a08560ff6001918060081c60005282602052161b60406000205416151590565b610a5d576104b360208a51980188611084565b8652602401602086015b828210610a4d575050509386945b845186101561055e5760208660051b86010151908181106000146105505788526020528587205b947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461052357600101946104cb565b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b9088526020528587206104f2565b9186918989947f000000000000000000000000000000000000000000000000000000000000000003610a245783517f5fe3b56700000000000000000000000000000000000000000000000000000000815260208160048173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610a1a5786916109eb575b5084517fdcf844a700000000000000000000000000000000000000000000000000000000815260208160248173ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001696876004840152165afa9081156109e15787916109ab575b50610982578360081c86526001602052848620600160ff86161b81541790558451906106a38261101d565b86825286602083015273ffffffffffffffffffffffffffffffffffffffff875416865193610100850190858210908211176109555787528352876020840152838684015260608301527f0000000000000000000000000000000000000000000000000000000000000000151560808301527f0000000000000000000000000000000000000000000000000000000000000000151560a083015284516107478161101d565b64ffffffffff600254818116835260281c16602082015260c083015260e0820152602060e08551927fab167ccc00000000000000000000000000000000000000000000000000000000845273ffffffffffffffffffffffffffffffffffffffff815116600485015273ffffffffffffffffffffffffffffffffffffffff838201511660248501526fffffffffffffffffffffffffffffffff8782015116604485015273ffffffffffffffffffffffffffffffffffffffff606082015116606485015260808101511515608485015260a0810151151560a485015264ffffffffff8360c08301518281511660c488015201511660e4850152015173ffffffffffffffffffffffffffffffffffffffff8151166101048401520151610124820152602081610144818873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af194851561094a5780956108ef575b5050937f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d838593602097825191825288820152a351908152f35b9095919294506020863d602011610942575b8161090e60209383611084565b810103126103115750935192907f28b58397e03322f670d6b223cc863f8c148e368b8b615412e6798a641a22842d836108b5565b3d9150610901565b8451903d90823e3d90fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b600485517fa4432b51000000000000000000000000000000000000000000000000000000008152fd5b90506020813d6020116109d9575b816109c660209383611084565b810103126109d5575188610678565b8680fd5b3d91506109b9565b86513d89823e3d90fd5b610a0d915060203d602011610a13575b610a058183611084565b810190611102565b876105fc565b503d6109fb565b85513d88823e3d90fd5b600484517fb3f3b2a6000000000000000000000000000000000000000000000000000000008152fd5b81358152602091820191016104bd565b6024858a51907f3548783b0000000000000000000000000000000000000000000000000000000082526004820152fd5b88517f74b43bd00000000000000000000000000000000000000000000000000000000081524260048201527f000000000000000000000000000000000000000000000000000000000000000064ffffffffff166024820152604490fd5b8880fd5b8580fd5b8380fd5b8280fd5b5090346103115780600319360112610311575060025464ffffffffff825191818116835260281c166020820152f35b50346100ed57816003193601126100ed57602090517f000000000000000000000000000000000000000000000000000000000000000015158152f35b50346100ed57816003193601126100ed57602090517f000000000000000000000000000000000000000000000000000000000000000015158152f35b91905034610af65780600319360112610af657610bbc610ff5565b916024356fffffffffffffffffffffffffffffffff8116809103610ff15773ffffffffffffffffffffffffffffffffffffffff9182865416338103610fa85750508251917f5fe3b5670000000000000000000000000000000000000000000000000000000083526020928381600481857f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f9e578791610f81575b5084517fdcf844a7000000000000000000000000000000000000000000000000000000008152848160248186807f00000000000000000000000000000000000000000000000000000000000000001696876004840152165afa908115610f77578891610f46575b50610cce6110c5565b159081610f3d575b50610ee057845190878084878501997fa9059cbb000000000000000000000000000000000000000000000000000000008b52169889602486015286604486015260448552610d2385611068565b885194610d2f8661101d565b8886527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656489870152519082855af13d15610ed2573d9167ffffffffffffffff8311610ea55790610dbc939291885192610daf897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160185611084565b83523d8b8985013e61112e565b8051848115918215610e85575b5050905015610e0257907f2e9d425ba8b27655048400b366d7b6a1f7180ebdb088e06bb7389704860ffe1f92918654169351908152a380f35b6084838551907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b83809293500103126109d55783015180151581036109d557808438610dc9565b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b90610dbc929160609161112e565b84517f1351f21d0000000000000000000000000000000000000000000000000000000081524260048201527f000000000000000000000000000000000000000000000000000000000000000064ffffffffff166024820152604490fd5b90501538610cd6565b90508481813d8311610f70575b610f5d8183611084565b81010312610f6c575138610cc5565b8780fd5b503d610f53565b86513d8a823e3d90fd5b610f989150843d8611610a1357610a058183611084565b38610c5e565b85513d89823e3d90fd5b7fc6cce6a400000000000000000000000000000000000000000000000000000000825273ffffffffffffffffffffffffffffffffffffffff166004820152336024820152604490fd5b8480fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361101857565b600080fd5b6040810190811067ffffffffffffffff82111761103957604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761103957604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761103957604052565b64ffffffffff7f00000000000000000000000000000000000000000000000000000000000000001680151590816110fa575090565b905042101590565b90816020910312611018575173ffffffffffffffffffffffffffffffffffffffff811681036110185790565b919290156111a95750815115611142575090565b3b1561114b5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156111bc5750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b848110611239575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b8181018301518682016044015285935082016111f856fea164736f6c6343000815000aa164736f6c6343000815000a"; - bytes public constant BYTECODE_PROXY_TARGET_APPROVE = - hex"60a0806040523461002357306080526147df90816100298239608051816136bb0152f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c806308b1834a14612db05780630a3b8c7714612c705780630d7fe86314612ab75780632104b57d146127645780632f5c8223146123da57806365092a79146123725780636a09d49a1461228557806379bcb2e314611f3b5780637d2085b014611d8b57806386f2891e14611d1357806391c68e991461192557806398590ef9146117235780639dc29fac146116a8578063a3143b761461162f578063ad26c0fb146115a4578063b76d0a58146112e9578063b82027bf14611035578063b956b45f14610f8a578063c44d5f7814610dbf578063d4f880f814610b8e578063ec4ac9a7146108a1578063ed233b3414610622578063edc1e8a014610439578063f16306121461028a5763f2bf799e1461013057600080fd5b3461023c576003199060808236011261023c5761014b6131e4565b9167ffffffffffffffff6024358181116102865761016d903690600401613532565b92909161017861320e565b9060643590811161028257610191903690600401613532565b92909661019c6136b1565b6001600160a01b0380911694853b1561027e576101ef9060409995949951977fa2ffb897000000000000000000000000000000000000000000000000000000008952606060048a01526064890191613674565b9716602486015284870301604485015280865260208096019195855b82811061024a57868087818180890381838c5af1801561023f5761022c5750f35b61023590613252565b61023c5780f35b80fd5b6040513d84823e3d90fd5b90919282806001926fffffffffffffffffffffffffffffffff61026c8c6133c4565b1681520198019101969291909661020b565b8780fd5b8580fd5b8380fd5b503461023c57604060031936011261023c5767ffffffffffffffff600435818111610435576102bd903690600401613532565b916024918235828111610282576102d8903690600401613532565b9390926102e36136b1565b851561040b5786906102f58686614411565b93825b88811061030e578361030b89898961455e565b80f35b610319818a84613605565b356001600160a01b03811680910361040757610336828b85613605565b60209081810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561027e570180359086821161027e578201928160051b3603841361027e57803b1561027e57888880946103cc604051978896879586947f8659c2700000000000000000000000000000000000000000000000000000000086526004860152840191613674565b03925af19081156103fc5785916103e8575b50506001016102f8565b6103f190613252565b6102865783386103de565b6040513d87823e3d90fd5b8480fd5b60046040517f71594532000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b506003199060408236011261023c576104506131e4565b916024359067ffffffffffffffff90818311610286576101409083360301126104355760405190610480826132b2565b61048c836004016131fa565b825261049a60248401613453565b94602095868401526104ae60448501613398565b60408401526104bf60648501613398565b60608401526104d0608485016131fa565b60808401526104e160a485016133c4565b9160a084019283526104f560c486016131fa565b9460c0850195865261050a3660e483016133f7565b60e086015261012481013591821161061e57013660238201121561028257926105916105c6938796936105488a973690602460048201359101613465565b6101008501526105566136b1565b6fffffffffffffffffffffffffffffffff9081341683526001600160a01b0380916105838289511661463d565b16955116915116908461422f565b6040519485809481937fc33cd35e00000000000000000000000000000000000000000000000000000000835260048301613e71565b03925af191821561061257916105e0575b50604051908152f35b90508181813d831161060b575b6105f78183613323565b810103126106065751386105d7565b600080fd5b503d6105ed565b604051903d90823e3d90fd5b8680fd5b503461023c5760031960a08136011261089d5761063d6131e4565b916024359161064a61320e565b916064359167ffffffffffffffff908184116104355761012090843603011261089d5760843590811161089d57610685903690600401613224565b505061068f6136b1565b6106976136b1565b6001600160a01b0380951690604051947feac8f5b80000000000000000000000000000000000000000000000000000000086528060048701526020968787602481875afa96871561089257839761085a575b50861690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528986602481875afa9586156103fc57859661082b575b50813b156104075784916024839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af18015610820578992918591610807575b505060246040518094819382523060048301525afa91821561061257916107d6575b50936107b66107c5926107ce9661370d565b906107bf6144df565b90613749565b60040190613f97565b604051908152f35b9490508585813d8311610800575b6107ee8183613323565b810103126106065793516107b66107a4565b503d6107e4565b61081391929350613252565b6104355787908338610782565b6040513d86823e3d90fd5b9095508981813d8311610853575b6108438183613323565b8101031261060657519438610732565b503d610839565b9096508781813d831161088b575b6108728183613323565b81010312610435575186811681036104355795386106e9565b503d610868565b6040513d85823e3d90fd5b5080fd5b503461023c576108b036613597565b50509190926108bd6136b1565b821561040b5784805b848210610b575761094f915061093f6001600160a01b036108e56144df565b9216916001600160a01b03604051917f23b872dd0000000000000000000000000000000000000000000000000000000060208401521660248201523060448201528260648201526064815261093981613307565b856137bd565b836001600160a01b03841661422f565b61095883613a7e565b93855b848110610974576040518061097088826134f7565b0390f35b60c0610981828785613e31565b01906109996040610993838987613e31565b01613acd565b6109af60806109a9848a88613e31565b01613ada565b6109c86109bd848a88613e31565b610100810190613ccb565b91906109dd6109d8868c8a613e31565b613ada565b9260206109eb878d8b613e31565b01359264ffffffffff84168403610b5357610ae4976fffffffffffffffffffffffffffffffff8a6001600160a01b038f94819960209b64ffffffffff610aab9b8f6060610993828d610a51610a9f9f610a4b610a57978f9260a093613e31565b01613a61565b9b613e31565b936040519e8f91610a67836132b2565b169052168d8d0152151560408c0152151560608b01521660808901521660a08701526001600160a01b038c1660c087015236906133f7565b60e08501523691613465565b610100820152604051809481927fc33cd35e00000000000000000000000000000000000000000000000000000000835260048301613e71565b03818b6001600160a01b0389165af18015610b48578890610b15575b60019250610b0e8289613b94565b520161095b565b506020823d602011610b40575b81610b2f60209383613323565b810103126106065760019151610b00565b3d9150610b22565b6040513d8a823e3d90fd5b8d80fd5b6001600160a01b036001916fffffffffffffffffffffffffffffffff610b8360a0610a4b878b8d613e31565b1601169101906108c6565b503461023c5761018060031936011261023c57610ba96131e4565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610164359067ffffffffffffffff821161023c5750610bf8903690600401613224565b5050610c026136b1565b608435906001600160a01b0382811691811682840361060657606435926fffffffffffffffffffffffffffffffff841680940361060657610ca084610c456144df565b96610c9a6040518760209a7f23b872dd000000000000000000000000000000000000000000000000000000008c84015216602482015230604482015283606482015260648152610c9481613307565b826137bd565b8461422f565b604051937fab167ccc0000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283359081168091036106065760e4850152610124908135908116809103610606576000859384928896840152610144938435908401525af1908115610db357600091610d865750604051908152f35b908282813d8311610dac575b610d9c8183613323565b8101031261023c575051386105d7565b503d610d92565b6040513d6000823e3d90fd5b5061016060031936011261023c57610dd56131e4565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c5760405191610e0e83613295565b610e16613364565b8352610e2061320e565b9260209384820152610e306133a5565b9060408101918252610e406133e1565b60608201908152610e4f61337a565b6080830152610e5c613389565b60a083015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c36011261060657604051610e97816132cf565b64ffffffffff60e4358181168103610606578252610104359081168103610606578782015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedc3601126106065760405191610ef8836132cf565b610124356001600160a01b03948582168203610606578796899686610f55946105c69852610144358982015260e0860152610f316136b1565b806fffffffffffffffffffffffffffffffff9283341685526105838289511661463d565b6040519485809481937fab167ccc00000000000000000000000000000000000000000000000000000000835260048301613aee565b503461023c57608060031936011261023c5780610fa56131e4565b610fad61320e565b610fb56133a5565b91610fbe6136b1565b6001600160a01b03809116803b15610407578492836064926fffffffffffffffffffffffffffffffff60405197889687957ffdd46d6000000000000000000000000000000000000000000000000000000000875260243560048801521660248601521660448401525af1801561023f5761022c5750f35b503461023c5761104436613597565b505091926110506136b1565b821561040b578490855b8481106112b257506001600160a01b036110e49116916110dd6001600160a01b036110836144df565b9216916001600160a01b03604051917f23b872dd000000000000000000000000000000000000000000000000000000006020840152166024820152306044820152826064820152606481526110d781613307565b876137bd565b858361422f565b6110ed83613a7e565b93855b848110611105576040518061097088826134f7565b611110818686613c8b565b60a0019061111f818787613c8b565b60200161112b90613acd565b611136828888613c8b565b60600161114290613ada565b9261114e838989613c8b565b60e0810161115b91613ccb565b919092611169858b8b613c8b565b61117290613ada565b9561117e868c8c613c8b565b60800161118a90613a61565b91611196878d8d613c8b565b6040016111a290613acd565b90604051986111b08a613295565b6001600160a01b0316895215156020890152151560408801526001600160a01b031660608701526fffffffffffffffffffffffffffffffff1660808601526001600160a01b03861660a086015236611207916133f7565b60c0850152369061121792613465565b60e0830152836040518080947f16844456000000000000000000000000000000000000000000000000000000008252600482019061125491613d1f565b03818b5a94602095f18015610b4857889061127f575b600192506112788289613b94565b52016110f0565b506020823d6020116112aa575b8161129960209383613323565b81010312610606576001915161126a565b3d915061128c565b916001600160a01b036001916fffffffffffffffffffffffffffffffff6112df6080610a4b888b8b613c8b565b160116920161105a565b503461023c576003199060608236011261023c576113056131e4565b9067ffffffffffffffff90816024351161023c5761014080946024353603011261023c5760443591821161023c5750611342903690600401613224565b505061134c6136b1565b6113e961135d60c460243501613ada565b6fffffffffffffffffffffffffffffffff61137c60a460243501613a61565b16906113da6113896144df565b6001600160a01b03604051917f23b872dd00000000000000000000000000000000000000000000000000000000602084015216602482015230604482015283606482015260648152610c9481613307565b6001600160a01b03841661422f565b60405180927fc33cd35e0000000000000000000000000000000000000000000000000000000082526020600483015261016482016001600160a01b036114336024356004016131fa565b16602484015264ffffffffff61144c6024803501613453565b166044840152611460604460243501613398565b15156064840152611475606460243501613398565b151560848401526001600160a01b036114926084602435016131fa565b1660a48401526fffffffffffffffffffffffffffffffff6114b760a4602435016133c4565b1660c48401526001600160a01b036114d360c4602435016131fa565b1660e48401526114ec610104840160e460243501613c6c565b6115016101246024350160243560040161418b565b91829193610144860152526101848301919060005b81811061158257505050918160006001600160a01b03826020960393165af1908115610db35760009161154f575b602082604051908152f35b6020813d60201161157a575b8161156860209383613323565b8101031261089d575190506020611544565b3d915061155b565b9193509160608082611596600194886141de565b019401910191859392611516565b503461023c57806001600160a01b036115bc36613563565b9290916115c76136b1565b1691823b1561162a576040517fc156a11d00000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b031660248201529082908290818381604481015b03925af1801561023f5761022c5750f35b505050fd5b503461023c57806001600160a01b0361164736613563565b9290916116526136b1565b1691823b1561162a576040517fea5ead1900000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b03166024820152908290829081838160448101611619565b503461023c57604060031936011261023c57806001600160a01b036116cb6131e4565b6116d36136b1565b16803b15611720578180916024604051809481937f42966c68000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b50fd5b503461023c57604060031936011261023c5761173d6131e4565b6024356117486136b1565b6001600160a01b0380921691604051917feac8f5b8000000000000000000000000000000000000000000000000000000008352806004840152846020928385602481895afa94851561023f5782956118ed575b50841691604051957f70a0823100000000000000000000000000000000000000000000000000000000918288523060048901528588602481885afa9788156108205784986118ba575b50813b156102865783916024839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af19283156118ad578593611894575b505060246040518094819382523060048301525afa9182156103fc578592611864575b505061030b926107b69161370d565b90809250813d831161188d575b61187b8183613323565b810103126106065751826107b6611855565b503d611871565b6118a091929350613252565b6102825782908638611832565b50604051903d90823e3d90fd5b86809299508195503d83116118e6575b6118d48183613323565b810103126106065787925196386117e4565b503d6118ca565b9094508381813d831161191e575b6119058183613323565b8101031261089d5751848116810361089d57933861179b565b503d6118fb565b503461023c576101e060031936011261023c576119406131e4565b602480359161194d61320e565b6101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610407576101c43567ffffffffffffffff811161028257611999903690600401613224565b50506119a36136b1565b6119ab6136b1565b6001600160a01b03809216604051907feac8f5b800000000000000000000000000000000000000000000000000000000825285600483015260209586838781855afa928315610b48578893611cdb575b508785841691604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528a868b81885afa958615610820578496611ca8575b50813b156102865783918a839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af19283156118ad578a93611c8b575b5050876040518094819382523060048301525afa908115610b48578596979891611c53575b50611ac692916107b69161370d565b611ace6136b1565b169060c435818116908181036106065760a435906fffffffffffffffffffffffffffffffff82168092036106065781611b5a91611b54611b0c6144df565b87604051917f23b872dd000000000000000000000000000000000000000000000000000000008d840152168a82015230604482015283606482015260648152610c9481613307565b8661422f565b604051947f96ce143100000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a485015264ffffffffff916101248035848116908190036106065760c48701526101449384358181168091036106065760e48801526101649384359182168092036106065787015261018435918216809203610606578694869485936000938501526101a435908401525af1908115610db357600091610d865750604051908152f35b9450909190508684813d8111611c84575b611c6e8183613323565b8101031261060657925184939190611ac6611ab7565b503d611c64565b611c9791929350613252565b611ca45787908938611a92565b8880fd5b8b809297508195503d8311611cd4575b611cc28183613323565b81010312610606578a92519438611a45565b503d611cb8565b9092508681813d8311611d0c575b611cf38183613323565b8101031261027e5751848116810361027e5791386119fb565b503d611ce9565b503461023c57604060031936011261023c57806001600160a01b03611d366131e4565b611d3e6136b1565b16803b15611720578180916024604051809481937f7de6b1db000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b503461023c576101a060031936011261023c57611da66131e4565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610184359067ffffffffffffffff821161023c5750611df5903690600401613224565b5050611dff6136b1565b608435906001600160a01b0382811691811682840361060657606435926fffffffffffffffffffffffffffffffff841680940361060657611e4284610c456144df565b604051937f96ce14310000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283358181168091036106065760e486015261012493843591821680920361060657850152610144908135908116809103610606576000859384928896840152610164938435908401525af1908115610db357600091610d865750604051908152f35b503461023c5760808060031936011261089d57611f566131e4565b90611f5f613364565b906044359267ffffffffffffffff9182851161028257366023860112156102825784600401359280841161061e57602486019560243691610120870201011161061e5760643590811161061e57611fba903690600401613224565b5050611fc46136b1565b821561040b57928591865b868582106122485750506001600160a01b0380911661204d82611ff06144df565b9516612046604051856020987f23b872dd000000000000000000000000000000000000000000000000000000008a8401521660248201523060448201528260648201526064815261204081613307565b866137bd565b848361422f565b61205685613a7e565b9682899416935b86811061207257604051806109708b826134f7565b61207d818884613a50565b60e00190868960608a8161209286838a613a50565b0161209c90613acd565b8a6120a887848b613a50565b938360a0978d8c8b836120bc828785613a50565b016120c690613ada565b986120d092613a50565b6120d990613ada565b988d8c6120e7818784613a50565b6040016120f390613a61565b956120fd92613a50565b0161210790613acd565b96816040519a6121168c613295565b168a5216908801526fffffffffffffffffffffffffffffffff16604087015285015215158d8401521515838301528036037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001604013610606576121e8948a936121ae926121916040519261218a846132cf565b8201613453565b82526121a060c0809201613453565b8683015284015236906133f7565b60e08201528c60405180809681947fab167ccc00000000000000000000000000000000000000000000000000000000835260048301613aee565b0391885af1801561223d578b9061220f575b60019250612208828c613b94565b520161205d565b508682813d8311612236575b6122258183613323565b8101031261060657600191516121fa565b503d61221b565b6040513d8d823e3d90fd5b81946fffffffffffffffffffffffffffffffff6122786040610a4b6001968b6001600160a01b03979d9a9d613a50565b1601169301949194611fcf565b503461023c57606060031936011261023c5761229f6131e4565b8167ffffffffffffffff602435818111610435576122c1903690600401613532565b92909160443590811161089d576122dc903690600401613532565b6122e46136b1565b6001600160a01b036122f68686614411565b961691823b1561028657612344928492836040518096819582947f8659c270000000000000000000000000000000000000000000000000000000008452602060048501526024840191613674565b03925af1801561023f5761235e575b505061030b9261455e565b61236790613252565b610286578338612353565b503461023c576003199060608236011261023c5761238e6131e4565b916024359167ffffffffffffffff9182841161089d5761012090843603011261023c5760443591821161023c5760206107ce85856123cf3660048801613224565b505060040190613f97565b503461023c576101c060031936011261023c576123f56131e4565b602480359161240261320e565b6101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610407576101a43567ffffffffffffffff81116102825761244e903690600401613224565b50506124586136b1565b6124606136b1565b6001600160a01b03809216604051907feac8f5b800000000000000000000000000000000000000000000000000000000825285600483015260209586838781855afa928315610b4857889361272c575b508785841691604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528a868b81885afa9586156108205784966126f9575b50813b156102865783918a839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af19283156118ad578a936126e0575b5050876040518094819382523060048301525afa908115610b485785969798916126a8575b5061257b92916107b69161370d565b6125836136b1565b169060c435818116908181036106065760a435906fffffffffffffffffffffffffffffffff821680920361060657816125c191611b54611b0c6144df565b604051947fab167ccc00000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a48501526101249182359164ffffffffff928381168091036106065760c48701526101449283359081168091036106065760e4870152610164359182168092036106065786948694859360009385015261018435908401525af1908115610db357600091610d865750604051908152f35b9450909190508684813d81116126d9575b6126c38183613323565b810103126106065792518493919061257b61256c565b503d6126b9565b6126ec91929350613252565b611ca45787908938612547565b8b809297508195503d8311612725575b6127138183613323565b81010312610606578a925194386124fa565b503d612709565b9092508681813d831161275d575b6127448183613323565b8101031261027e5751848116810361027e5791386124b0565b503d61273a565b503461023c576080908160031936011261023c576127806131e4565b90612789613364565b67ffffffffffffffff9260443584811161028657366023820112156102865780600401359480861161040757602482019160243691610140890201011161040757606435908111610407576127e2903690600401613224565b50506127ec6136b1565b841561040b579091839190825b868110612a7a57506001600160a01b0380941661286f856128186144df565b9516612868604051886020987f23b872dd000000000000000000000000000000000000000000000000000000008a8401521660248201523060448201528260648201526064815261093981613307565b838361422f565b61287887613a7e565b9685879316925b81811061289457604051806109708b826134f7565b806128a18b928488613ba8565b610100018660608a816128b5868986613ba8565b016128bf90613acd565b956128cb868986613ba8565b96888d806128da8a848a613ba8565b016128e490613ada565b94846128f18b858b613ba8565b6128fa90613ada565b988b612907818784613ba8565b60400161291390613a61565b9561291d92613ba8565b0161292790613acd565b9581604051996129368b613295565b16895216908701526fffffffffffffffffffffffffffffffff1660408601528a84860152151590840152151560a08301528436037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600112610606576129e18992612a1995604051906129a7826132eb565b6129b360a08201613453565b82526129d260e060c0926129c8848201613453565b8986015201613453565b604083015284015236906133f7565b60e0820152604051809481927f96ce143100000000000000000000000000000000000000000000000000000000835260048301613bb9565b03818c885af18015612a6f578990612a41575b60019250612a3a828c613b94565b520161287f565b508682813d8311612a68575b612a578183613323565b810103126106065760019151612a2c565b503d612a4d565b6040513d8b823e3d90fd5b926001600160a01b036001916fffffffffffffffffffffffffffffffff612aaa6040610a4b898d8a9c999c613ba8565b16011693019390936127f9565b5061018060031936011261023c57612acd6131e4565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c5760405191612b0683613295565b612b0e613364565b8352612b1861320e565b9260209384820152612b286133a5565b9060408101918252612b386133e1565b60608201908152612b4761337a565b6080830152612b54613389565b60a083015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c36011261060657604051612b8f816132eb565b64ffffffffff60e4358181168103610606578252610104358181168103610606578883015261012435908116810361060657604082015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebc3601126106065760405191612c02836132cf565b610144356001600160a01b03948582168203610606578796899686612c3b946105c69852610164358982015260e0860152610f316136b1565b6040519485809481937f96ce143100000000000000000000000000000000000000000000000000000000835260048301613bb9565b506003199060408236011261023c57612c876131e4565b916024359067ffffffffffffffff90818311610286576101209083360301126104355760405190612cb782613295565b612cc3836004016131fa565b8252612cd160248401613398565b9460209586840152612ce560448501613398565b6040840152612cf6606485016131fa565b6060840152612d07608485016133c4565b9160808401928352612d1b60a486016131fa565b9460a08501958652612d303660c483016133f7565b60c086015261010481013591821161061e5701366023820112156102825792612d7b6105c693879693612d6e8a973690602460048201359101613465565b60e08501526105566136b1565b6040519485809481937f1684445600000000000000000000000000000000000000000000000000000000835260048301613d1f565b503461023c576003199060a08236011261023c57612dcc6131e4565b906024803593612dda61320e565b6064359367ffffffffffffffff80861161089d576101408660040194873603011261089d5760843590811161089d57612e17903690600401613224565b5050612e216136b1565b612e296136b1565b6001600160a01b03809616604051917feac8f5b800000000000000000000000000000000000000000000000000000000835288600484015260209889848881865afa93841561023f5782946131ac575b5088841690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528c868b81875afa9586156103fc57859661317d575b50813b156104075784918a839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af1801561082057908c929161316a575b50886040518094819382523060048301525afa91821561061257908995949392613135575b5089979694939291612f469161370d565b612f4e6144df565b612f5792613749565b612f5f6136b1565b169160c4840193612f6f85613ada565b9660a48201956fffffffffffffffffffffffffffffffff9889612f9189613a61565b16612f9a6144df565b84604051918c83017f23b872dd000000000000000000000000000000000000000000000000000000009052168882015230604482015281606482015260648152612fe381613307565b612fed90836137bd565b612ff7918861422f565b6040519889977fc33cd35e0000000000000000000000000000000000000000000000000000000089528960048a015261016489019684613036886131fa565b16818b0152850161304690613453565b64ffffffffff1660448a01526044850161305f90613398565b151560648a01526064850161307390613398565b151560848a01528360848601613088906131fa565b1660a48a0152613097906133c4565b1660c48801526130a6906131fa565b1660e4860152610104850160e48201906130bf91613c6c565b610124016130cc9161418b565b6101406101448601529182905261018484019160005b81811061310c57505050600083809203925af1908115610db357600091610d865750604051908152f35b9290939550819450613120816001936141de565b606080910194019101908694928694926130e2565b809295508a8092503d8311613163575b61314f8183613323565b810103126106065751879390612f46612f35565b503d613145565b61317690949194613252565b9238612f10565b9095508c81813d83116131a5575b6131958183613323565b8101031261040757519438612ec2565b503d61318b565b9093508981813d83116131dd575b6131c48183613323565b8101031261089d5751888116810361089d579238612e79565b503d6131ba565b600435906001600160a01b038216820361060657565b35906001600160a01b038216820361060657565b604435906001600160a01b038216820361060657565b9181601f840112156106065782359167ffffffffffffffff8311610606576020838186019501011161060657565b67ffffffffffffffff811161326657604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610100810190811067ffffffffffffffff82111761326657604052565b610120810190811067ffffffffffffffff82111761326657604052565b6040810190811067ffffffffffffffff82111761326657604052565b6060810190811067ffffffffffffffff82111761326657604052565b60a0810190811067ffffffffffffffff82111761326657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761326657604052565b602435906001600160a01b038216820361060657565b60a43590811515820361060657565b60c43590811515820361060657565b3590811515820361060657565b606435906fffffffffffffffffffffffffffffffff8216820361060657565b35906fffffffffffffffffffffffffffffffff8216820361060657565b608435906001600160a01b038216820361060657565b91908260409103126106065760405161340f816132cf565b602080829461341d816131fa565b84520135910152565b67ffffffffffffffff81116132665760051b60200190565b359067ffffffffffffffff8216820361060657565b359064ffffffffff8216820361060657565b92919261347182613426565b60409461348086519283613323565b8195848352602080930191606080960285019481861161060657925b8584106134ac5750505050505050565b86848303126106065784879184516134c3816132eb565b6134cc876133c4565b81526134d983880161343e565b838201526134e8868801613453565b8682015281520193019261349c565b6020908160408183019282815285518094520193019160005b82811061351e575050505090565b835185529381019392810192600101613510565b9181601f840112156106065782359167ffffffffffffffff8311610606576020808501948460051b01011161060657565b6003196060910112610606576001600160a01b03600435818116810361060657916024359160443590811681036106065790565b6080600319820112610606576001600160a01b0391600435838116810361060657926024359081168103610606579167ffffffffffffffff9160443583811161060657826135e791600401613532565b939093926064359182116106065761360191600401613224565b9091565b91908110156136455760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc181360301821215610606570190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116106065760209260051b809284830137010190565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630146136e357565b60046040517fbbff6135000000000000000000000000000000000000000000000000000000008152fd5b9190820391821161371a57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000060208201526001600160a01b039290921660248301526044808301939093529181526137a39161379e606483613323565b6137bd565b565b90816020910312610606575180151581036106065790565b60405161381b916001600160a01b03166137d6826132cf565b6000806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af16138156138d0565b9161392e565b8051908282159283156138b8575b505050156138345750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b6138c893508201810191016137a5565b388281613829565b3d15613929573d9067ffffffffffffffff8211613266576040519161391d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184613323565b82523d6000602084013e565b606090565b919290156139a95750815115613942575090565b3b1561394b5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156139bc5750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b848110613a39575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b8181018301518682016044015285935082016139f8565b919081101561364557610120020190565b356fffffffffffffffffffffffffffffffff811681036106065790565b90613a8882613426565b613a956040519182613323565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0613ac38294613426565b0190602036910137565b3580151581036106065790565b356001600160a01b03811681036106065790565b6137a39092919261010060e06101408301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151602064ffffffffff918281511660c0880152015116828501520151910190602080916001600160a01b0381511684520151910152565b80518210156136455760209160051b010190565b919081101561364557610140020190565b6137a39092919261012060e06101608301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151604064ffffffffff918281511660c088015282602082015116858801520151166101008501520151910190602080916001600160a01b0381511684520151910152565b602080916001600160a01b03613c81826131fa565b1684520135910152565b91908110156136455760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0181360301821215610606570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610606570180359067ffffffffffffffff82116106065760200191606082023603831361060657565b9060208083526101408301908061016060e06001600160a01b0395868151168489015283810151151560408901526040810151966060971515888a015280888301511660808a01526fffffffffffffffffffffffffffffffff60808301511660a08a015260a08201511660c0890152613db260c0820151838a0190602080916001600160a01b0381511684520151910152565b015195610120808201528651809552019401926000905b838210613dd857505050505090565b9091929394838282613e246001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b0196019493920190613dc9565b91908110156136455760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee181360301821215610606570190565b906020808352610160830190806101806001600160a01b0394858151168388015264ffffffffff8382015116604088015260408101519560609615158789015286820151151560808901528060808301511660a08901526fffffffffffffffffffffffffffffffff60a08301511660c089015260c08201511660e088015260e081015190613f1861010092838a0190602080916001600160a01b0381511684520151910152565b015195610140808201528651809552019401926000905b838210613f3e57505050505090565b9091929394838282613f8a6001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b0196019493920190613f2f565b907f23b872dd000000000000000000000000000000000000000000000000000000006140d792613fc56136b1565b6001600160a01b0380911660a0840191613fde83613ada565b946140f860808201916fffffffffffffffffffffffffffffffff936140458561400686613a61565b1661400f6144df565b9a61403f6040518560209e8f9e8f84015216602482015230604482015283606482015260648152610c9481613307565b8861422f565b604051998a977f168444560000000000000000000000000000000000000000000000000000000089528960048a015261014489019683614084866131fa565b1660248b01526140958b8601613398565b151560448b01526140a860408601613398565b151560648b01526140cc606097856140c18a89016131fa565b1660848d01526133c4565b1660a48a01526131fa565b1660c48701526140ed60e4870160c08301613c6c565b61010081019061418b565b809193610120610124880152526101648501929160005b8281106141645750505050600083809203925af1908115610db357600091614138575b50905090565b82813d831161415d575b61414c8183613323565b8101031261023c5750518038614132565b503d614142565b929550600191949650808461417a8296896141de565b01950191019287949287969461410f565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561060657016020813591019167ffffffffffffffff821161060657606082023603831361060657565b64ffffffffff614229604080936fffffffffffffffffffffffffffffffff614205826133c4565b16865267ffffffffffffffff61421d6020830161343e565b16602087015201613453565b16910152565b91906001600160a01b039283821690604051947fdd62ed3e0000000000000000000000000000000000000000000000000000000086523060048701528116918260248701526020958681604481855afa8015610db35786916000916143d1575b501061429e575b505050505050565b60008060405196614320886142f48b8201937f095ea7b3000000000000000000000000000000000000000000000000000000009889865260248401602090939291936001600160a01b0360408201951681520152565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018a5289613323565b87519082855af1906143306138d0565b8261439e575b5081614393575b501561434a575b80614296565b60405194850152602484015260006044840152604483526080830183811067ffffffffffffffff821117613266576143899361379e91604052826137bd565b3880808080614344565b90503b15153861433d565b8091925051908782159283156143b9575b5050509038614336565b6143c993508201810191016137a5565b3887816143af565b91508782813d83116143fa575b6143e88183613323565b8101031261023c57508590513861428f565b503d6143de565b91908110156136455760051b0190565b91909161441d83613a7e565b9260005b81811061442d57505050565b6001600160a01b036144436109d8838587614401565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa9182156144d557506000916144a4575b506001925061449d8288613b94565b5201614421565b919282813d83116144ce575b6144ba8183613323565b8101031261023c575090600191513861448e565b503d6144b0565b513d6000823e3d90fd5b6040517f8da5cb5b000000000000000000000000000000000000000000000000000000008152602081600481305afa908115610db357600091614520575090565b6020813d8211614556575b8161453860209383613323565b8101031261089d5751906001600160a01b038216820361023c575090565b3d915061452b565b909160005b8181106145705750505050565b6001600160a01b036145866109d8838588614401565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa9182156144d5575060009161460a575b50600192506145ee614604916145e78488613b94565b519061370d565b6145fc6109d884878a614401565b6107bf6144df565b01614563565b919282813d8311614636575b6146208183613323565b8101031261023c575051600191906145ee6145d1565b503d614616565b6001600160a01b031660409081517f70a08231000000000000000000000000000000000000000000000000000000008082526000903060048401526020908184602481885afa9384156147c8578394614799575b50843b156104355785517fd0e30db00000000000000000000000000000000000000000000000000000000081528381600481348a5af1801561478f5761477c575b508190602487518097819382523060048301525afa9182156147715791614741575b506146ff925061370d565b9034820361470b575050565b6044925051907fe5f762580000000000000000000000000000000000000000000000000000000082523460048301526024820152fd5b905082813d831161476a575b6147578183613323565b81010312610606576146ff9151386146f4565b503d61474d565b8551903d90823e3d90fd5b92614788839294613252565b92906146d2565b87513d86823e3d90fd5b9093508181813d83116147c1575b6147b18183613323565b8101031261043557519238614691565b503d6147a7565b86513d85823e3d90fdfea164736f6c6343000815000a"; - bytes public constant BYTECODE_PROXY_TARGET_PERMIT2 = - hex"60c0346200007d57601f6200465438819003918201601f19168301916001600160401b0383118484101762000082578084926020946040528339810103126200007d57516001600160a01b03811681036200007d573060805260a0526040516145bb90816200009982396080518161304f015260a0518161369e0152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001257600080fd5b6000803560e01c806308b1834a1461294d5780630a3b8c771461280d5780630d7fe863146126545780632104b57d146123645780632f5c822314611fde57806365092a7914611f755780636a09d49a14611e8857806379bcb2e314611b9f5780637d2085b0146119eb57806386f2891e1461197357806391c68e99146115ae57806398590ef9146113ac5780639dc29fac14611331578063a3143b76146112b8578063ad26c0fb1461122d578063b76d0a58146111c4578063b82027bf14610f7f578063b956b45f14610ed4578063c44d5f7814610d09578063d4f880f814610b25578063ec4ac9a71461089e578063ed233b3414610622578063edc1e8a014610439578063f16306121461028a5763f2bf799e1461013057600080fd5b3461023c576003199060808236011261023c5761014b612b94565b9167ffffffffffffffff6024358181116102865761016d903690600401612ec6565b929091610178612bbe565b9060643590811161028257610191903690600401612ec6565b92909661019c613045565b6001600160a01b0380911694853b1561027e576101ef9060409995949951977fa2ffb897000000000000000000000000000000000000000000000000000000008952606060048a01526064890191613008565b9716602486015284870301604485015280865260208096019195855b82811061024a57868087818180890381838c5af1801561023f5761022c5750f35b61023590612c02565b61023c5780f35b80fd5b6040513d84823e3d90fd5b90919282806001926fffffffffffffffffffffffffffffffff61026c8c612d58565b1681520198019101969291909661020b565b8780fd5b8580fd5b8380fd5b503461023c57604060031936011261023c5767ffffffffffffffff600435818111610435576102bd903690600401612ec6565b916024918235828111610282576102d8903690600401612ec6565b9390926102e3613045565b851561040b5786906102f586866141ed565b93825b88811061030e578361030b89898961433a565b80f35b610319818a84612f99565b356001600160a01b03811680910361040757610336828b85612f99565b60209081810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561027e570180359086821161027e578201928160051b3603841361027e57803b1561027e57888880946103cc604051978896879586947f8659c2700000000000000000000000000000000000000000000000000000000086526004860152840191613008565b03925af19081156103fc5785916103e8575b50506001016102f8565b6103f190612c02565b6102865783386103de565b6040513d87823e3d90fd5b8480fd5b60046040517f71594532000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b506003199060408236011261023c57610450612b94565b916024359067ffffffffffffffff9081831161028657610140908336030112610435576040519061048082612c62565b61048c83600401612baa565b825261049a60248401612de7565b94602095868401526104ae60448501612d2c565b60408401526104bf60648501612d2c565b60608401526104d060848501612baa565b60808401526104e160a48501612d58565b9160a084019283526104f560c48601612baa565b9460c0850195865261050a3660e48301612d8b565b60e086015261012481013591821161061e57013660238201121561028257926105916105c6938796936105488a973690602460048201359101612df9565b610100850152610556613045565b6fffffffffffffffffffffffffffffffff9081341683526001600160a01b03809161058382895116614419565b16955116915116908461400b565b6040519485809481937fc33cd35e00000000000000000000000000000000000000000000000000000000835260048301613b17565b03925af191821561061257916105e0575b50604051908152f35b90508181813d831161060b575b6105f78183612cb7565b810103126106065751386105d7565b600080fd5b503d6105ed565b604051903d90823e3d90fd5b8680fd5b503461023c576003199060a08236011261023c5761063e612b94565b916024359161064b612bbe565b6064359267ffffffffffffffff90818511610286576101209085360301126104355760843590811161043557610685903690600401612bd4565b939092610690613045565b610698613045565b6001600160a01b0380971690604051967feac8f5b80000000000000000000000000000000000000000000000000000000088528060048901526020988989602481875afa98891561089357839961085b575b50881690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528b86602481875afa9586156103fc57859661082c575b50813b156104075784916024839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af18015610821578b92918591610808575b505060246040518094819382523060048301525afa91821561061257916107d7575b50956107b76107c6926107cf986130a1565b906107c06142bb565b906130dd565b60040190613c3d565b604051908152f35b9690508787813d8311610801575b6107ef8183612cb7565b810103126106065795516107b76107a5565b503d6107e5565b61081491929350612c02565b6104355789908338610783565b6040513d86823e3d90fd5b9095508b81813d8311610854575b6108448183612cb7565b8101031261060657519438610733565b503d61083a565b9098508981813d831161088c575b6108738183612cb7565b81010312610435575188811681036104355797386106ea565b503d610869565b6040513d85823e3d90fd5b503461023c576108ad36612f2b565b906108bb9592949395613045565b841561040b5786875b8688818310610aee57505050906108e69291856001600160a01b038616613567565b6108ef8361342a565b93855b84811061090b57604051806109078882612e8b565b0390f35b60c0610918828785613ad7565b0190610930604061092a838987613ad7565b01613479565b6109466080610940848a88613ad7565b01613486565b61095f610954848a88613ad7565b610100810190613971565b919061097461096f868c8a613ad7565b613486565b926020610982878d8b613ad7565b01359264ffffffffff84168403610aea57610a7b976fffffffffffffffffffffffffffffffff8a6001600160a01b038f94819960209b64ffffffffff610a429b8f606061092a828d6109e8610a369f6109e26109ee978f9260a093613ad7565b0161340d565b9b613ad7565b936040519e8f916109fe83612c62565b169052168d8d0152151560408c0152151560608b01521660808901521660a08701526001600160a01b038c1660c08701523690612d8b565b60e08501523691612df9565b610100820152604051809481927fc33cd35e00000000000000000000000000000000000000000000000000000000835260048301613b17565b03818b6001600160a01b0389165af18015610adf578890610aac575b60019250610aa58289613540565b52016108f2565b506020823d602011610ad7575b81610ac660209383612cb7565b810103126106065760019151610a97565b3d9150610ab9565b6040513d8a823e3d90fd5b8d80fd5b926fffffffffffffffffffffffffffffffff610b1b60a06109e2866001600160a01b039660019899613ad7565b16011691016108c4565b503461023c5761018060031936011261023c57610b40612b94565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610164359067ffffffffffffffff821161023c5750610b8f903690600401612bd4565b610b9a929192613045565b6001600160a01b03809216906084358381169182820361060657606435956fffffffffffffffffffffffffffffffff87168097036106065786610bdd9386613567565b604051937fab167ccc0000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283359081168091036106065760e485015261012490813590811680910361060657600085938492602096840152610144938435908401525af1908115610cfd57600091610cc7575b602082604051908152f35b6020813d8211610cf5575b81610cdf60209383612cb7565b81010312610cf1575190506020610cbc565b5080fd5b3d9150610cd2565b6040513d6000823e3d90fd5b5061016060031936011261023c57610d1f612b94565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c5760405191610d5883612c45565b610d60612cf8565b8352610d6a612bbe565b9260209384820152610d7a612d39565b9060408101918252610d8a612d75565b60608201908152610d99612d0e565b6080830152610da6612d1d565b60a083015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c36011261060657604051610de181612c7f565b64ffffffffff60e4358181168103610606578252610104359081168103610606578782015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedc3601126106065760405191610e4283612c7f565b610124356001600160a01b03948582168203610606578796899686610e9f946105c69852610144358982015260e0860152610e7b613045565b806fffffffffffffffffffffffffffffffff92833416855261058382895116614419565b6040519485809481937fab167ccc0000000000000000000000000000000000000000000000000000000083526004830161349a565b503461023c57608060031936011261023c5780610eef612b94565b610ef7612bbe565b610eff612d39565b91610f08613045565b6001600160a01b03809116803b15610407578492836064926fffffffffffffffffffffffffffffffff60405197889687957ffdd46d6000000000000000000000000000000000000000000000000000000000875260243560048801521660248601521660448401525af1801561023f5761022c5750f35b503461023c57610f8e36612f2b565b610f9b9594919295613045565b851561040b578692875b8780821061118d57505090610fc7916001600160a01b03809716948486613567565b610fd08561342a565b94865b818110610fe857604051806109078982612e8b565b610ff3818387613931565b60a001908583611004838284613931565b60200161101090613479565b93818a61101e868387613931565b60600161102a90613486565b86611036818589613931565b60e0810161104391613971565b9661104f929198613931565b61105890613486565b978c88611066818784613931565b6080016110729061340d565b9561107c92613931565b60400161108890613479565b90836040519a6110978c612c45565b168a52151560208a0152151560408901521660608701526fffffffffffffffffffffffffffffffff16608086015289871660a0860152366110d791612d8b565b60c085015236906110e792612df9565b60e0830152846040518080947f168444560000000000000000000000000000000000000000000000000000000082526004820190611124916139c5565b03818c5a94602095f1801561118257899061114f575b60019250611148828a613540565b5201610fd3565b506020823d60201161117a575b8161116960209383612cb7565b81010312610606576001915161113a565b3d915061115c565b6040513d8b823e3d90fd5b81956fffffffffffffffffffffffffffffffff6111ba60806109e26001966001600160a01b03968d613931565b1601169401610fa5565b503461023c576003199060608236011261023c576111e0612b94565b916024359167ffffffffffffffff91828411610cf15761014090843603011261023c5760443591821161023c5760206107cf85856112213660048801612bd4565b92909160040190613e84565b503461023c57806001600160a01b0361124536612ef7565b929091611250613045565b1691823b156112b3576040517fc156a11d00000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b031660248201529082908290818381604481015b03925af1801561023f5761022c5750f35b505050fd5b503461023c57806001600160a01b036112d036612ef7565b9290916112db613045565b1691823b156112b3576040517fea5ead1900000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b031660248201529082908290818381604481016112a2565b503461023c57604060031936011261023c57806001600160a01b03611354612b94565b61135c613045565b16803b156113a9578180916024604051809481937f42966c68000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b50fd5b503461023c57604060031936011261023c576113c6612b94565b6024356113d1613045565b6001600160a01b0380921691604051917feac8f5b8000000000000000000000000000000000000000000000000000000008352806004840152846020928385602481895afa94851561023f578295611576575b50841691604051957f70a0823100000000000000000000000000000000000000000000000000000000918288523060048901528588602481885afa978815610821578498611543575b50813b156102865783916024839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af192831561153657859361151d575b505060246040518094819382523060048301525afa9182156103fc5785926114ed575b505061030b926107b7916130a1565b90809250813d8311611516575b6115048183612cb7565b810103126106065751826107b76114de565b503d6114fa565b61152991929350612c02565b61028257829086386114bb565b50604051903d90823e3d90fd5b86809299508195503d831161156f575b61155d8183612cb7565b8101031261060657879251963861146d565b503d611553565b9094508381813d83116115a7575b61158e8183612cb7565b81010312610cf157518481168103610cf1579338611424565b503d611584565b503461023c576101e060031936011261023c576115c9612b94565b906024908135926115d8612bbe565b6101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610435576101c43567ffffffffffffffff811161028657611624903690600401612bd4565b91909361162f613045565b611637613045565b6001600160a01b03809416604051917feac8f5b800000000000000000000000000000000000000000000000000000000835288600484015260209889848a81865afa93841561023f57829461193b575b5086841690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528c868d81875afa9586156103fc57859661190c575b50813b156104075784918c839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af18015610821578c929185916118f3575b50508a6040518094819382523060048301525afa918215610612579087959493926118bb575b5061175492916107b7916130a1565b61175c613045565b169260c435838116928382036106065760a435926fffffffffffffffffffffffffffffffff841680940361060657836117959388613567565b604051947f96ce143100000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a485015264ffffffffff916101248035848116908190036106065760c48701526101449384358181168091036106065760e48801526101649384359182168092036106065787015261018435918216809203610606578694869485936000938501526101a435908401525af1908115610cfd5760009161188e5750604051908152f35b908282813d83116118b4575b6118a48183612cb7565b8101031261023c575051386105d7565b503d61189a565b9450909190508884813d81116118ec575b6118d68183612cb7565b8101031261060657925185939190611754611745565b503d6118cc565b6118ff91929350612c02565b610435578a90833861171f565b9095508c81813d8311611934575b6119248183612cb7565b81010312610606575194386116d0565b503d61191a565b9093508981813d831161196c575b6119538183612cb7565b81010312610cf157518681168103610cf1579238611687565b503d611949565b503461023c57604060031936011261023c57806001600160a01b03611996612b94565b61199e613045565b16803b156113a9578180916024604051809481937f7de6b1db000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b503461023c576101a060031936011261023c57611a06612b94565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610184359067ffffffffffffffff821161023c5750611a55903690600401612bd4565b611a60929192613045565b6001600160a01b03809216906084358381169182820361060657606435956fffffffffffffffffffffffffffffffff87168097036106065786611aa39386613567565b604051937f96ce14310000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283358181168091036106065760e48601526101249384359182168092036106065785015261014490813590811680910361060657600085938492602096840152610164938435908401525af1908115610cfd57600091610cc757602082604051908152f35b503461023c576080908160031936011261023c57611bbb612b94565b90611bc4612cf8565b60443567ffffffffffffffff938482116102865736602383011215610286578160040135948086116104075760248301926024369161012089020101116104075760643590811161040757611c1d903690600401612bd4565b611c28969196613045565b811561040b5785949194508596865b868110611e4b575090611c57916001600160a01b0380951698848a613567565b611c608461342a565b9582869216915b858110611c7c57604051806109078a82612e8b565b611c878187876133fc565b60e00190606080611c99838a8a6133fc565b01611ca390613479565b9287898d611cb28683856133fc565b968960209687611cc38a87896133fc565b01611ccd90613486565b948d85611cdb8c848b6133fc565b611ce490613486565b988c611cf18186846133fc565b604001611cfd9061340d565b94611d07926133fc565b01611d1190613479565b968160405199611d208b612c45565b16895216898801526fffffffffffffffffffffffffffffffff166040870152850152151590830152151560a08201528436037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160401361060657611dba8392611df29660405190611d9182612c7f565b611d9d60a08201612de7565b8252611dac60c0809201612de7565b868301528401523690612d8b565b60e0820152604051809581927fab167ccc0000000000000000000000000000000000000000000000000000000083526004830161349a565b03818c885af1908115611182578991611e1c575b5060019250611e15828b613540565b5201611c67565b905082813d8311611e44575b611e328183612cb7565b81010312610606576001915138611e06565b503d611e28565b976001600160a01b036001916fffffffffffffffffffffffffffffffff611e7b60406109e28e8d8d9e9b9e6133fc565b1601169801959295611c37565b503461023c57606060031936011261023c57611ea2612b94565b8167ffffffffffffffff60243581811161043557611ec4903690600401612ec6565b929091604435908111610cf157611edf903690600401612ec6565b611ee7613045565b6001600160a01b03611ef986866141ed565b961691823b1561028657611f47928492836040518096819582947f8659c270000000000000000000000000000000000000000000000000000000008452602060048501526024840191613008565b03925af1801561023f57611f61575b505061030b9261433a565b611f6a90612c02565b610286578338611f56565b503461023c576003199060608236011261023c57611f91612b94565b916024359167ffffffffffffffff91828411610cf15761012090843603011261023c5760443591821161023c5760206107cf8585611fd23660048801612bd4565b92909160040190613c3d565b503461023c576101c060031936011261023c57611ff9612b94565b90602490813592612008612bbe565b6101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610435576101a43567ffffffffffffffff811161028657612054903690600401612bd4565b91909361205f613045565b612067613045565b6001600160a01b03809416604051917feac8f5b800000000000000000000000000000000000000000000000000000000835288600484015260209889848a81865afa93841561023f57829461232c575b5086841690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528c868d81875afa9586156103fc5785966122fd575b50813b156104075784918c839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af18015610821578c929185916122e4575b50508a6040518094819382523060048301525afa918215610612579087959493926122ac575b5061218492916107b7916130a1565b61218c613045565b169260c435838116928382036106065760a435926fffffffffffffffffffffffffffffffff841680940361060657836121c59388613567565b604051947fab167ccc00000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a48501526101249182359164ffffffffff928381168091036106065760c48701526101449283359081168091036106065760e4870152610164359182168092036106065786948694859360009385015261018435908401525af1908115610cfd5760009161188e5750604051908152f35b9450909190508884813d81116122dd575b6122c78183612cb7565b8101031261060657925185939190612184612175565b503d6122bd565b6122f091929350612c02565b610435578a90833861214f565b9095508c81813d8311612325575b6123158183612cb7565b8101031261060657519438612100565b503d61230b565b9093508981813d831161235d575b6123448183612cb7565b81010312610cf157518681168103610cf15792386120b7565b503d61233a565b503461023c576080908160031936011261023c57612380612b94565b90612389612cf8565b60443567ffffffffffffffff9384821161028657366023830112156102865781600401359480861161040757602483019260243691610140890201011161040757606435908111610407576123e2903690600401612bd4565b6123ed969196613045565b811561040b578596865b83811061261d575090612417916001600160a01b0380951698878a613567565b6124208161342a565b9582869516945b82811061243c57604051806109078a82612e8b565b61244781848761384e565b610100019089606092878461245d85898461384e565b0161246790613479565b9461247385898461384e565b9560209485612483888c8761384e565b0161248d90613486565b918a8c8361249c8b848a61384e565b6124a590613486565b978b6124b281868461384e565b6040016124be9061340d565b946124c89261384e565b016124d290613479565b9481604051986124e18a612c45565b16885216888701526fffffffffffffffffffffffffffffffff1660408601528d84860152151590840152151560a08301528536037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001126106065761258c83926125c4966040519061255282612c9b565b61255e60a08201612de7565b825261257d60e060c092612573848201612de7565b8986015201612de7565b60408301528401523690612d8b565b60e0820152604051809581927f96ce14310000000000000000000000000000000000000000000000000000000083526004830161385f565b03818c885af19081156111825789916125ee575b50600192506125e7828b613540565b5201612427565b905082813d8311612616575b6126048183612cb7565b810103126106065760019151386125d8565b503d6125fa565b976001600160a01b036001916fffffffffffffffffffffffffffffffff61264a60406109e28e8a8d61384e565b16011698016123f7565b5061018060031936011261023c5761266a612b94565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57604051916126a383612c45565b6126ab612cf8565b83526126b5612bbe565b92602093848201526126c5612d39565b90604081019182526126d5612d75565b606082019081526126e4612d0e565b60808301526126f1612d1d565b60a083015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c3601126106065760405161272c81612c9b565b64ffffffffff60e4358181168103610606578252610104358181168103610606578883015261012435908116810361060657604082015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebc360112610606576040519161279f83612c7f565b610144356001600160a01b039485821682036106065787968996866127d8946105c69852610164358982015260e0860152610e7b613045565b6040519485809481937f96ce14310000000000000000000000000000000000000000000000000000000083526004830161385f565b506003199060408236011261023c57612824612b94565b916024359067ffffffffffffffff9081831161028657610120908336030112610435576040519061285482612c45565b61286083600401612baa565b825261286e60248401612d2c565b946020958684015261288260448501612d2c565b604084015261289360648501612baa565b60608401526128a460848501612d58565b91608084019283526128b860a48601612baa565b9460a085019586526128cd3660c48301612d8b565b60c086015261010481013591821161061e57013660238201121561028257926129186105c69387969361290b8a973690602460048201359101612df9565b60e0850152610556613045565b6040519485809481937f16844456000000000000000000000000000000000000000000000000000000008352600483016139c5565b503461023c576003199060a08236011261023c57612969612b94565b9160243591612976612bbe565b6064359267ffffffffffffffff908185116102865761014090853603011261043557608435908111610435576129b0903690600401612bd4565b9390926129bb613045565b6129c3613045565b6001600160a01b0380971690604051967feac8f5b80000000000000000000000000000000000000000000000000000000088528060048901526020988989602481875afa988915610893578399612b5c575b50881690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528b86602481875afa9586156103fc578596612b2d575b50813b156104075784916024839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af1801561082157908b9291612b1a575b5060246040518094819382523060048301525afa9182156106125791612ae9575b50956107b7612ae0926107cf986130a1565b60040190613e84565b9690508787813d8311612b13575b612b018183612cb7565b810103126106065795516107b7612ace565b503d612af7565b612b2690949194612c02565b9238612aad565b9095508b81813d8311612b55575b612b458183612cb7565b8101031261040757519438612a5e565b503d612b3b565b9098508981813d8311612b8d575b612b748183612cb7565b8101031261043557518881168103610435579738612a15565b503d612b6a565b600435906001600160a01b038216820361060657565b35906001600160a01b038216820361060657565b604435906001600160a01b038216820361060657565b9181601f840112156106065782359167ffffffffffffffff8311610606576020838186019501011161060657565b67ffffffffffffffff8111612c1657604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610100810190811067ffffffffffffffff821117612c1657604052565b610120810190811067ffffffffffffffff821117612c1657604052565b6040810190811067ffffffffffffffff821117612c1657604052565b6060810190811067ffffffffffffffff821117612c1657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117612c1657604052565b602435906001600160a01b038216820361060657565b60a43590811515820361060657565b60c43590811515820361060657565b3590811515820361060657565b606435906fffffffffffffffffffffffffffffffff8216820361060657565b35906fffffffffffffffffffffffffffffffff8216820361060657565b608435906001600160a01b038216820361060657565b919082604091031261060657604051612da381612c7f565b6020808294612db181612baa565b84520135910152565b67ffffffffffffffff8111612c165760051b60200190565b359067ffffffffffffffff8216820361060657565b359064ffffffffff8216820361060657565b929192612e0582612dba565b604094612e1486519283612cb7565b8195848352602080930191606080960285019481861161060657925b858410612e405750505050505050565b8684830312610606578487918451612e5781612c9b565b612e6087612d58565b8152612e6d838801612dd2565b83820152612e7c868801612de7565b86820152815201930192612e30565b6020908160408183019282815285518094520193019160005b828110612eb2575050505090565b835185529381019392810192600101612ea4565b9181601f840112156106065782359167ffffffffffffffff8311610606576020808501948460051b01011161060657565b6003196060910112610606576001600160a01b03600435818116810361060657916024359160443590811681036106065790565b6080600319820112610606576001600160a01b0391600435838116810361060657926024359081168103610606579167ffffffffffffffff916044358381116106065782612f7b91600401612ec6565b9390939260643591821161060657612f9591600401612bd4565b9091565b9190811015612fd95760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc181360301821215610606570190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116106065760209260051b809284830137010190565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016301461307757565b60046040517fbbff6135000000000000000000000000000000000000000000000000000000008152fd5b919082039182116130ae57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000060208201526001600160a01b0392909216602483015260448083019390935291815261313791613132606483612cb7565b61318b565b565b67ffffffffffffffff8111612c1657601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b90816020910312610606575180151581036106065790565b6040516131e9916001600160a01b03166131a482612c7f565b6000806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af16131e361329e565b916132ce565b805190828215928315613286575b505050156132025750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b6132969350820181019101613173565b3882816131f7565b3d156132c9573d906132af82613139565b916132bd6040519384612cb7565b82523d6000602084013e565b606090565b9192901561334957508151156132e2575090565b3b156132eb5790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b82519091501561335c5750805190602001fd5b61339a906040519182917f08c379a000000000000000000000000000000000000000000000000000000000835260206004840152602483019061339e565b0390fd5b919082519283825260005b8481106133e85750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b6020818301810151848301820152016133a9565b9190811015612fd957610120020190565b356fffffffffffffffffffffffffffffffff811681036106065790565b9061343482612dba565b6134416040519182612cb7565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061346f8294612dba565b0190602036910137565b3580151581036106065790565b356001600160a01b03811681036106065790565b6131379092919261010060e06101408301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151602064ffffffffff918281511660c0880152015116828501520151910190602080916001600160a01b0381511684520151910152565b8051821015612fd95760209160051b010190565b359065ffffffffffff8216820361060657565b9091929493850192600095602091828287031261027e57813567ffffffffffffffff9283821161384a57018087039660e0881261384a576040938451926135ad84612c7f565b60c08a1261384657608086519a6135c38c612c9b565b126138465785519960808b018b8110848211176138195787528c9291906135e982612baa565b8c526001600160a01b039b828a01358d81168103610282578a820152613610898401613554565b8982015261362060608401613554565b6060820152815261363360808301612baa565b8982015260a082013588820152855260c0810135918211610435570182601f82011215610cf157803561366581613139565b9361367288519586612cb7565b81855288828401011161043557808880930183860137830101528482019081528961369b6142bb565b897f0000000000000000000000000000000000000000000000000000000000000000169351925190843b156104355761375c8b9492888694815197889687967f2b67b570000000000000000000000000000000000000000000000000000000008852169c8d6004880152825182815116602489015282828201511660448901526060858201519165ffffffffffff80931660648b015201511660848801528201511660a4860152015160c484015261010060e484015261010483019061339e565b038183865af1801561380f576137fa575b50908189923b1561043557879483608492865197889586947f36c785160000000000000000000000000000000000000000000000000000000086526004860152306024860152169a8b60448501528a1660648401525af19081156137f157506137dd575b5061313793945061400b565b6137e78691612c02565b61040757846137d1565b513d88823e3d90fd5b6138079099919299612c02565b97903861376d565b84513d8c823e3d90fd5b60248e7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b8b80fd5b8980fd5b9190811015612fd957610140020190565b6131379092919261012060e06101608301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151604064ffffffffff918281511660c088015282602082015116858801520151166101008501520151910190602080916001600160a01b0381511684520151910152565b602080916001600160a01b0361392782612baa565b1684520135910152565b9190811015612fd95760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0181360301821215610606570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610606570180359067ffffffffffffffff82116106065760200191606082023603831361060657565b9060208083526101408301908061016060e06001600160a01b0395868151168489015283810151151560408901526040810151966060971515888a015280888301511660808a01526fffffffffffffffffffffffffffffffff60808301511660a08a015260a08201511660c0890152613a5860c0820151838a0190602080916001600160a01b0381511684520151910152565b015195610120808201528651809552019401926000905b838210613a7e57505050505090565b9091929394838282613aca6001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b0196019493920190613a6f565b9190811015612fd95760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee181360301821215610606570190565b906020808352610160830190806101806001600160a01b0394858151168388015264ffffffffff8382015116604088015260408101519560609615158789015286820151151560808901528060808301511660a08901526fffffffffffffffffffffffffffffffff60a08301511660c089015260c08201511660e088015260e081015190613bbe61010092838a0190602080916001600160a01b0381511684520151910152565b015195610140808201528651809552019401926000905b838210613be457505050505090565b9091929394838282613c306001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b0196019493920190613bd5565b613d2c929193613c4b613045565b6001600160a01b038092169060a0860193613c92613c6886613486565b9260808901926fffffffffffffffffffffffffffffffff9485613c8a8661340d565b169087613567565b613d4d6040519788957f1684445600000000000000000000000000000000000000000000000000000000875260209889988960048a015261014489019683613cd986612baa565b1660248b0152613cea8b8601612d2c565b151560448b0152613cfd60408601612d2c565b151560648b0152613d2160609785613d168a8901612baa565b1660848d0152612d58565b1660a48a0152612baa565b1660c4870152613d4260e4870160c08301613912565b610100810190613de0565b809193610120610124880152526101648501929160005b828110613db95750505050600083809203925af1908115610cfd57600091613d8d575b50905090565b82813d8311613db2575b613da18183612cb7565b8101031261023c5750518038613d87565b503d613d97565b9295506001919496508084613dcf829689613e33565b019501910192879492879694613d64565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561060657016020813591019167ffffffffffffffff821161060657606082023603831361060657565b64ffffffffff613e7e604080936fffffffffffffffffffffffffffffffff613e5a82612d58565b16865267ffffffffffffffff613e7260208301612dd2565b16602087015201612de7565b16910152565b613f83929193613e92613045565b6001600160a01b038092169060c0860193613ed1613eaf86613486565b9260a08901926fffffffffffffffffffffffffffffffff9485613c8a8661340d565b613fa56040519788957fc33cd35e00000000000000000000000000000000000000000000000000000000875260209889988960048a015261016489019683613f1886612baa565b1660248b015264ffffffffff613f2f8c8701612de7565b1660448b0152613f4160408601612d2c565b151560648b0152613f78606097613f59898801612d2c565b151560848d015285613f6d60808901612baa565b1660a48d0152612d58565b1660c48a0152612baa565b1660e4870152613f9a610104870160e08301613912565b610120810190613de0565b809193610140610144880152526101848501929160005b828110613fe45750505050600083809203925af1908115610cfd57600091613d8d5750905090565b9295506001919496508084613ffa829689613e33565b019501910192879492879694613fbc565b91906001600160a01b039283821690604051947fdd62ed3e0000000000000000000000000000000000000000000000000000000086523060048701528116918260248701526020958681604481855afa8015610cfd5786916000916141ad575b501061407a575b505050505050565b600080604051966140fc886140d08b8201937f095ea7b3000000000000000000000000000000000000000000000000000000009889865260248401602090939291936001600160a01b0360408201951681520152565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018a5289612cb7565b87519082855af19061410c61329e565b8261417a575b508161416f575b5015614126575b80614072565b60405194850152602484015260006044840152604483526080830183811067ffffffffffffffff821117612c165761416593613132916040528261318b565b3880808080614120565b90503b151538614119565b809192505190878215928315614195575b5050509038614112565b6141a59350820181019101613173565b38878161418b565b91508782813d83116141d6575b6141c48183612cb7565b8101031261023c57508590513861406b565b503d6141ba565b9190811015612fd95760051b0190565b9190916141f98361342a565b9260005b81811061420957505050565b6001600160a01b0361421f61096f8385876141dd565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa9182156142b15750600091614280575b50600192506142798288613540565b52016141fd565b919282813d83116142aa575b6142968183612cb7565b8101031261023c575090600191513861426a565b503d61428c565b513d6000823e3d90fd5b6040517f8da5cb5b000000000000000000000000000000000000000000000000000000008152602081600481305afa908115610cfd576000916142fc575090565b6020813d8211614332575b8161431460209383612cb7565b81010312610cf15751906001600160a01b038216820361023c575090565b3d9150614307565b909160005b81811061434c5750505050565b6001600160a01b0361436261096f8385886141dd565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa9182156142b157506000916143e6575b50600192506143ca6143e0916143c38488613540565b51906130a1565b6143d861096f84878a6141dd565b6107c06142bb565b0161433f565b919282813d8311614412575b6143fc8183612cb7565b8101031261023c575051600191906143ca6143ad565b503d6143f2565b6001600160a01b031660409081517f70a08231000000000000000000000000000000000000000000000000000000008082526000903060048401526020908184602481885afa9384156145a4578394614575575b50843b156104355785517fd0e30db00000000000000000000000000000000000000000000000000000000081528381600481348a5af1801561456b57614558575b508190602487518097819382523060048301525afa91821561454d579161451d575b506144db92506130a1565b903482036144e7575050565b6044925051907fe5f762580000000000000000000000000000000000000000000000000000000082523460048301526024820152fd5b905082813d8311614546575b6145338183612cb7565b81010312610606576144db9151386144d0565b503d614529565b8551903d90823e3d90fd5b92614564839294612c02565b92906144ae565b87513d86823e3d90fd5b9093508181813d831161459d575b61458d8183612cb7565b810103126104355751923861446d565b503d614583565b86513d85823e3d90fdfea164736f6c6343000815000a"; - bytes public constant BYTECODE_PROXY_TARGET_PUSH = - hex"60a08060405234610023573060805261429590816100298239608051816130450152f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c806308b1834a146129445780630a3b8c77146128045780630d7fe8631461264b5780632104b57d1461235c5780632f5c822314611fd757806365092a7914611f6f5780636a09d49a14611e8257806379bcb2e314611b9b5780637d2085b0146119e957806386f2891e1461197157806391c68e99146115a957806398590ef9146113a75780639dc29fac1461132c578063a3143b76146112b3578063ad26c0fb14611228578063b76d0a58146111c0578063b82027bf14610f7e578063b956b45f14610ed3578063c44d5f7814610d08578063d4f880f814610b2a578063ec4ac9a7146108a1578063ed233b3414610622578063edc1e8a014610439578063f16306121461028a5763f2bf799e1461013057600080fd5b3461023c576003199060808236011261023c5761014b612b8a565b9167ffffffffffffffff6024358181116102865761016d903690600401612ebc565b929091610178612bb4565b9060643590811161028257610191903690600401612ebc565b92909661019c61303b565b6001600160a01b0380911694853b1561027e576101ef9060409995949951977fa2ffb897000000000000000000000000000000000000000000000000000000008952606060048a01526064890191612ffe565b9716602486015284870301604485015280865260208096019195855b82811061024a57868087818180890381838c5af1801561023f5761022c5750f35b61023590612bf8565b61023c5780f35b80fd5b6040513d84823e3d90fd5b90919282806001926fffffffffffffffffffffffffffffffff61026c8c612d4e565b1681520198019101969291909661020b565b8780fd5b8580fd5b8380fd5b503461023c57604060031936011261023c5767ffffffffffffffff600435818111610435576102bd903690600401612ebc565b916024918235828111610282576102d8903690600401612ebc565b9390926102e361303b565b851561040b5786906102f58686613ec7565b93825b88811061030e578361030b898989614014565b80f35b610319818a84612f8f565b356001600160a01b03811680910361040757610336828b85612f8f565b60209081810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561027e570180359086821161027e578201928160051b3603841361027e57803b1561027e57888880946103cc604051978896879586947f8659c2700000000000000000000000000000000000000000000000000000000086526004860152840191612ffe565b03925af19081156103fc5785916103e8575b50506001016102f8565b6103f190612bf8565b6102865783386103de565b6040513d87823e3d90fd5b8480fd5b60046040517f71594532000000000000000000000000000000000000000000000000000000008152fd5b8280fd5b506003199060408236011261023c57610450612b8a565b916024359067ffffffffffffffff9081831161028657610140908336030112610435576040519061048082612c58565b61048c83600401612ba0565b825261049a60248401612ddd565b94602095868401526104ae60448501612d22565b60408401526104bf60648501612d22565b60608401526104d060848501612ba0565b60808401526104e160a48501612d4e565b9160a084019283526104f560c48601612ba0565b9460c0850195865261050a3660e48301612d81565b60e086015261012481013591821161061e57013660238201121561028257926105916105c6938796936105488a973690602460048201359101612def565b61010085015261055661303b565b6fffffffffffffffffffffffffffffffff9081341683526001600160a01b038091610583828951166140f3565b169551169151169084613ce5565b6040519485809481937fc33cd35e000000000000000000000000000000000000000000000000000000008352600483016137fb565b03925af191821561061257916105e0575b50604051908152f35b90508181813d831161060b575b6105f78183612cad565b810103126106065751386105d7565b600080fd5b503d6105ed565b604051903d90823e3d90fd5b8680fd5b503461023c5760031960a08136011261089d5761063d612b8a565b916024359161064a612bb4565b916064359167ffffffffffffffff908184116104355761012090843603011261089d5760843590811161089d57610685903690600401612bca565b505061068f61303b565b61069761303b565b6001600160a01b0380951690604051947feac8f5b80000000000000000000000000000000000000000000000000000000086528060048701526020968787602481875afa96871561089257839761085a575b50861690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528986602481875afa9586156103fc57859661082b575b50813b156104075784916024839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af18015610820578992918591610807575b505060246040518094819382523060048301525afa91821561061257916107d6575b50936107b66107c5926107ce96613097565b906107bf613f95565b906130d3565b60040190613921565b604051908152f35b9490508585813d8311610800575b6107ee8183612cad565b810103126106065793516107b66107a4565b503d6107e4565b61081391929350612bf8565b6104355787908338610782565b6040513d86823e3d90fd5b9095508981813d8311610853575b6108438183612cad565b8101031261060657519438610732565b503d610839565b9096508781813d831161088b575b6108728183612cad565b81010312610435575186811681036104355795386106e9565b503d610868565b6040513d85823e3d90fd5b5080fd5b503461023c576108b036612f21565b50509190926108bd61303b565b821561040b5784855b848110610af357506001600160a01b036108eb9116836001600160a01b038416613ce5565b6108f483613408565b93855b848110610910576040518061090c8882612e81565b0390f35b60c061091d8287856137bb565b0190610935604061092f8389876137bb565b01613457565b61094b6080610945848a886137bb565b01613464565b610964610959848a886137bb565b610100810190613655565b9190610979610974868c8a6137bb565b613464565b926020610987878d8b6137bb565b01359264ffffffffff84168403610aef57610a80976fffffffffffffffffffffffffffffffff8a6001600160a01b038f94819960209b64ffffffffff610a479b8f606061092f828d6109ed610a3b9f6109e76109f3978f9260a0936137bb565b016133eb565b9b6137bb565b936040519e8f91610a0383612c58565b169052168d8d0152151560408c0152151560608b01521660808901521660a08701526001600160a01b038c1660c08701523690612d81565b60e08501523691612def565b610100820152604051809481927fc33cd35e000000000000000000000000000000000000000000000000000000008352600483016137fb565b03818b6001600160a01b0389165af18015610ae4578890610ab1575b60019250610aaa828961351e565b52016108f7565b506020823d602011610adc575b81610acb60209383612cad565b810103126106065760019151610a9c565b3d9150610abe565b6040513d8a823e3d90fd5b8d80fd5b906001600160a01b036001916fffffffffffffffffffffffffffffffff610b2060a06109e7878b8d6137bb565b16011691016108c6565b503461023c5761018060031936011261023c57610b45612b8a565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610164359067ffffffffffffffff821161023c5750610b94903690600401612bca565b5050610b9e61303b565b608435906001600160a01b0390811682821680840361060657606435936fffffffffffffffffffffffffffffffff85168095036106065784610be09184613ce5565b604051937fab167ccc0000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283359081168091036106065760e485015261012490813590811680910361060657600085938492602096840152610144938435908401525af1908115610cfc57600091610cca575b602082604051908152f35b6020813d8211610cf4575b81610ce260209383612cad565b8101031261089d575190506020610cbf565b3d9150610cd5565b6040513d6000823e3d90fd5b5061016060031936011261023c57610d1e612b8a565b906101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c5760405191610d5783612c3b565b610d5f612cee565b8352610d69612bb4565b9260209384820152610d79612d2f565b9060408101918252610d89612d6b565b60608201908152610d98612d04565b6080830152610da5612d13565b60a083015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c36011261060657604051610de081612c75565b64ffffffffff60e4358181168103610606578252610104359081168103610606578782015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedc3601126106065760405191610e4183612c75565b610124356001600160a01b03948582168203610606578796899686610e9e946105c69852610144358982015260e0860152610e7a61303b565b806fffffffffffffffffffffffffffffffff928334168552610583828951166140f3565b6040519485809481937fab167ccc00000000000000000000000000000000000000000000000000000000835260048301613478565b503461023c57608060031936011261023c5780610eee612b8a565b610ef6612bb4565b610efe612d2f565b91610f0761303b565b6001600160a01b03809116803b15610407578492836064926fffffffffffffffffffffffffffffffff60405197889687957ffdd46d6000000000000000000000000000000000000000000000000000000000875260243560048801521660248601521660448401525af1801561023f5761022c5750f35b503461023c57610f8d36612f21565b50509291610f9961303b565b831561040b578490855b8581106111895750610fc36001600160a01b038080961693168284613ce5565b610fcc85613408565b94865b818110610fe4576040518061090c8982612e81565b610fef818387613615565b60a001908583611000838284613615565b60200161100c90613457565b93818a61101a868387613615565b60600161102690613464565b86611032818589613615565b60e0810161103f91613655565b9661104b929198613615565b61105490613464565b978c88611062818784613615565b60800161106e906133eb565b9561107892613615565b60400161108490613457565b90836040519a6110938c612c3b565b168a52151560208a0152151560408901521660608701526fffffffffffffffffffffffffffffffff16608086015289871660a0860152366110d391612d81565b60c085015236906110e392612def565b60e0830152846040518080947f168444560000000000000000000000000000000000000000000000000000000082526004820190611120916136a9565b03818c5a94602095f1801561117e57899061114b575b60019250611144828a61351e565b5201610fcf565b506020823d602011611176575b8161116560209383612cad565b810103126106065760019151611136565b3d9150611158565b6040513d8b823e3d90fd5b916001600160a01b036001916fffffffffffffffffffffffffffffffff6111b660806109e7888c8b613615565b1601169201610fa3565b503461023c576003199060608236011261023c576111dc612b8a565b916024359167ffffffffffffffff9182841161089d5761014090843603011261023c5760443591821161023c5760206107ce858561121d3660048801612bca565b505060040190613b63565b503461023c57806001600160a01b0361124036612eed565b92909161124b61303b565b1691823b156112ae576040517fc156a11d00000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b031660248201529082908290818381604481015b03925af1801561023f5761022c5750f35b505050fd5b503461023c57806001600160a01b036112cb36612eed565b9290916112d661303b565b1691823b156112ae576040517fea5ead1900000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b0316602482015290829082908183816044810161129d565b503461023c57604060031936011261023c57806001600160a01b0361134f612b8a565b61135761303b565b16803b156113a4578180916024604051809481937f42966c68000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b50fd5b503461023c57604060031936011261023c576113c1612b8a565b6024356113cc61303b565b6001600160a01b0380921691604051917feac8f5b8000000000000000000000000000000000000000000000000000000008352806004840152846020928385602481895afa94851561023f578295611571575b50841691604051957f70a0823100000000000000000000000000000000000000000000000000000000918288523060048901528588602481885afa97881561082057849861153e575b50813b156102865783916024839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af1928315611531578593611518575b505060246040518094819382523060048301525afa9182156103fc5785926114e8575b505061030b926107b691613097565b90809250813d8311611511575b6114ff8183612cad565b810103126106065751826107b66114d9565b503d6114f5565b61152491929350612bf8565b61028257829086386114b6565b50604051903d90823e3d90fd5b86809299508195503d831161156a575b6115588183612cad565b81010312610606578792519638611468565b503d61154e565b9094508381813d83116115a2575b6115898183612cad565b8101031261089d5751848116810361089d57933861141f565b503d61157f565b503461023c576101e060031936011261023c576115c4612b8a565b60248035916115d1612bb4565b6101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610407576101c43567ffffffffffffffff81116102825761161d903690600401612bca565b505061162761303b565b61162f61303b565b6001600160a01b03809216604051907feac8f5b800000000000000000000000000000000000000000000000000000000825285600483015260209586838781855afa928315610ae4578893611939575b508785841691604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528a868b81885afa958615610820578496611906575b50813b156102865783918a839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af1928315611531578a936118e9575b5050876040518094819382523060048301525afa908115610ae45785969798916118b1575b5061174a92916107b691613097565b61175261303b565b169060c435818116908181036106065760a435906fffffffffffffffffffffffffffffffff8216809203610606578161178b9186613ce5565b604051947f96ce143100000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a485015264ffffffffff916101248035848116908190036106065760c48701526101449384358181168091036106065760e48801526101649384359182168092036106065787015261018435918216809203610606578694869485936000938501526101a435908401525af1908115610cfc576000916118845750604051908152f35b908282813d83116118aa575b61189a8183612cad565b8101031261023c575051386105d7565b503d611890565b9450909190508684813d81116118e2575b6118cc8183612cad565b810103126106065792518493919061174a61173b565b503d6118c2565b6118f591929350612bf8565b6119025787908938611716565b8880fd5b8b809297508195503d8311611932575b6119208183612cad565b81010312610606578a925194386116c9565b503d611916565b9092508681813d831161196a575b6119518183612cad565b8101031261027e5751848116810361027e57913861167f565b503d611947565b503461023c57604060031936011261023c57806001600160a01b03611994612b8a565b61199c61303b565b16803b156113a4578180916024604051809481937f7de6b1db000000000000000000000000000000000000000000000000000000008352833560048401525af1801561023f5761022c5750f35b503461023c576101a060031936011261023c57611a04612b8a565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c57610184359067ffffffffffffffff821161023c5750611a53903690600401612bca565b5050611a5d61303b565b608435906001600160a01b0390811682821680840361060657606435936fffffffffffffffffffffffffffffffff85168095036106065784611a9f9184613ce5565b604051937f96ce14310000000000000000000000000000000000000000000000000000000085526024358481168091036106065760048601526044358481168091036106065760248601526044850152606484015260a43580151580910361060657608484015260c4358015158091036106065760a484015260e4359164ffffffffff928381168091036106065760c48501526101049283358181168091036106065760e48601526101249384359182168092036106065785015261014490813590811680910361060657600085938492602096840152610164938435908401525af1908115610cfc57600091610cca57602082604051908152f35b503461023c576080908160031936011261023c57611bb7612b8a565b90611bc0612cee565b60443567ffffffffffffffff938482116102865736602383011215610286578160040135948086116104075760248301926024369161012089020101116104075760643590811161040757611c19903690600401612bca565b5050611c2361303b565b841561040b57929384939092845b848110611e455750611c516001600160a01b038080941697168288613ce5565b611c5a84613408565b9582869216915b858110611c76576040518061090c8a82612e81565b611c818187876133da565b60e00190606080611c93838a8a6133da565b01611c9d90613457565b9287898d611cac8683856133da565b968960209687611cbd8a87896133da565b01611cc790613464565b948d85611cd58c848b6133da565b611cde90613464565b988c611ceb8186846133da565b604001611cf7906133eb565b94611d01926133da565b01611d0b90613457565b968160405199611d1a8b612c3b565b16895216898801526fffffffffffffffffffffffffffffffff166040870152850152151590830152151560a08201528436037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160401361060657611db48392611dec9660405190611d8b82612c75565b611d9760a08201612ddd565b8252611da660c0809201612ddd565b868301528401523690612d81565b60e0820152604051809581927fab167ccc00000000000000000000000000000000000000000000000000000000835260048301613478565b03818c885af190811561117e578991611e16575b5060019250611e0f828b61351e565b5201611c61565b905082813d8311611e3e575b611e2c8183612cad565b81010312610606576001915138611e00565b503d611e22565b956001600160a01b036001916fffffffffffffffffffffffffffffffff611e7560406109e78c8b8b9c999c6133da565b1601169601939093611c31565b503461023c57606060031936011261023c57611e9c612b8a565b8167ffffffffffffffff60243581811161043557611ebe903690600401612ebc565b92909160443590811161089d57611ed9903690600401612ebc565b611ee161303b565b6001600160a01b03611ef38686613ec7565b961691823b1561028657611f41928492836040518096819582947f8659c270000000000000000000000000000000000000000000000000000000008452602060048501526024840191612ffe565b03925af1801561023f57611f5b575b505061030b92614014565b611f6490612bf8565b610286578338611f50565b503461023c576003199060608236011261023c57611f8b612b8a565b916024359167ffffffffffffffff9182841161089d5761012090843603011261023c5760443591821161023c5760206107ce8585611fcc3660048801612bca565b505060040190613921565b503461023c576101c060031936011261023c57611ff2612b8a565b6024803591611fff612bb4565b6101407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c360112610407576101a43567ffffffffffffffff81116102825761204b903690600401612bca565b505061205561303b565b61205d61303b565b6001600160a01b03809216604051907feac8f5b800000000000000000000000000000000000000000000000000000000825285600483015260209586838781855afa928315610ae4578893612324575b508785841691604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528a868b81885afa9586156108205784966122f1575b50813b156102865783918a839260405196879384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af1928315611531578a936122d8575b5050876040518094819382523060048301525afa908115610ae45785969798916122a0575b5061217892916107b691613097565b61218061303b565b169060c435818116908181036106065760a435906fffffffffffffffffffffffffffffffff821680920361060657816121b99186613ce5565b604051947fab167ccc00000000000000000000000000000000000000000000000000000000865260643584811680910361060657600487015260843590848216809203610606578601526044850152606484015260e43580151580910361060657608484015261010480358015158091036106065760a48501526101249182359164ffffffffff928381168091036106065760c48701526101449283359081168091036106065760e4870152610164359182168092036106065786948694859360009385015261018435908401525af1908115610cfc576000916118845750604051908152f35b9450909190508684813d81116122d1575b6122bb8183612cad565b8101031261060657925184939190612178612169565b503d6122b1565b6122e491929350612bf8565b6119025787908938612144565b8b809297508195503d831161231d575b61230b8183612cad565b81010312610606578a925194386120f7565b503d612301565b9092508681813d8311612355575b61233c8183612cad565b8101031261027e5751848116810361027e5791386120ad565b503d612332565b503461023c576080908160031936011261023c57612378612b8a565b90612381612cee565b60443567ffffffffffffffff9384821161028657366023830112156102865781600401359480861161040757602483019260243691610140890201011161040757606435908111610407576123da903690600401612bca565b50506123e461303b565b841561040b578394845b818110612614575061240e6001600160a01b038080941697168588613ce5565b61241781613408565b9582869516945b828110612433576040518061090c8a82612e81565b61243e818487613532565b6101000190896060928784612454858984613532565b0161245e90613457565b9461246a858984613532565b956020948561247a888c87613532565b0161248490613464565b918a8c836124938b848a613532565b61249c90613464565b978b6124a9818684613532565b6040016124b5906133eb565b946124bf92613532565b016124c990613457565b9481604051986124d88a612c3b565b16885216888701526fffffffffffffffffffffffffffffffff1660408601528d84860152151590840152151560a08301528536037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001126106065761258383926125bb966040519061254982612c91565b61255560a08201612ddd565b825261257460e060c09261256a848201612ddd565b8986015201612ddd565b60408301528401523690612d81565b60e0820152604051809581927f96ce143100000000000000000000000000000000000000000000000000000000835260048301613543565b03818c885af190811561117e5789916125e5575b50600192506125de828b61351e565b520161241e565b905082813d831161260d575b6125fb8183612cad565b810103126106065760019151386125cf565b503d6125f1565b956001600160a01b036001916fffffffffffffffffffffffffffffffff61264160406109e78c888b613532565b16011696016123ee565b5061018060031936011261023c57612661612b8a565b906101607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36011261023c576040519161269a83612c3b565b6126a2612cee565b83526126ac612bb4565b92602093848201526126bc612d2f565b90604081019182526126cc612d6b565b606082019081526126db612d04565b60808301526126e8612d13565b60a083015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1c3601126106065760405161272381612c91565b64ffffffffff60e4358181168103610606578252610104358181168103610606578883015261012435908116810361060657604082015260c083015260407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebc360112610606576040519161279683612c75565b610144356001600160a01b039485821682036106065787968996866127cf946105c69852610164358982015260e0860152610e7a61303b565b6040519485809481937f96ce143100000000000000000000000000000000000000000000000000000000835260048301613543565b506003199060408236011261023c5761281b612b8a565b916024359067ffffffffffffffff9081831161028657610120908336030112610435576040519061284b82612c3b565b61285783600401612ba0565b825261286560248401612d22565b946020958684015261287960448501612d22565b604084015261288a60648501612ba0565b606084015261289b60848501612d4e565b91608084019283526128af60a48601612ba0565b9460a085019586526128c43660c48301612d81565b60c086015261010481013591821161061e570136602382011215610282579261290f6105c6938796936129028a973690602460048201359101612def565b60e085015261055661303b565b6040519485809481937f16844456000000000000000000000000000000000000000000000000000000008352600483016136a9565b503461023c5760031960a08136011261089d5761295f612b8a565b916024359161296c612bb4565b916064359167ffffffffffffffff908184116104355761014090843603011261089d5760843590811161089d576129a7903690600401612bca565b50506129b161303b565b6129b961303b565b6001600160a01b0380951690604051947feac8f5b80000000000000000000000000000000000000000000000000000000086528060048701526020968787602481875afa968715610892578397612b52575b50861690604051937f70a0823100000000000000000000000000000000000000000000000000000000918286523060048701528986602481875afa9586156103fc578596612b23575b50813b156104075784916024839260405194859384927f40e58ee500000000000000000000000000000000000000000000000000000000845260048401525af180156108205790899291612b10575b5060246040518094819382523060048301525afa9182156106125791612adf575b50936107b6612ad6926107ce96613097565b60040190613b63565b9490508585813d8311612b09575b612af78183612cad565b810103126106065793516107b6612ac4565b503d612aed565b612b1c90949194612bf8565b9238612aa3565b9095508981813d8311612b4b575b612b3b8183612cad565b8101031261040757519438612a54565b503d612b31565b9096508781813d8311612b83575b612b6a8183612cad565b8101031261043557518681168103610435579538612a0b565b503d612b60565b600435906001600160a01b038216820361060657565b35906001600160a01b038216820361060657565b604435906001600160a01b038216820361060657565b9181601f840112156106065782359167ffffffffffffffff8311610606576020838186019501011161060657565b67ffffffffffffffff8111612c0c57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610100810190811067ffffffffffffffff821117612c0c57604052565b610120810190811067ffffffffffffffff821117612c0c57604052565b6040810190811067ffffffffffffffff821117612c0c57604052565b6060810190811067ffffffffffffffff821117612c0c57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117612c0c57604052565b602435906001600160a01b038216820361060657565b60a43590811515820361060657565b60c43590811515820361060657565b3590811515820361060657565b606435906fffffffffffffffffffffffffffffffff8216820361060657565b35906fffffffffffffffffffffffffffffffff8216820361060657565b608435906001600160a01b038216820361060657565b919082604091031261060657604051612d9981612c75565b6020808294612da781612ba0565b84520135910152565b67ffffffffffffffff8111612c0c5760051b60200190565b359067ffffffffffffffff8216820361060657565b359064ffffffffff8216820361060657565b929192612dfb82612db0565b604094612e0a86519283612cad565b8195848352602080930191606080960285019481861161060657925b858410612e365750505050505050565b8684830312610606578487918451612e4d81612c91565b612e5687612d4e565b8152612e63838801612dc8565b83820152612e72868801612ddd565b86820152815201930192612e26565b6020908160408183019282815285518094520193019160005b828110612ea8575050505090565b835185529381019392810192600101612e9a565b9181601f840112156106065782359167ffffffffffffffff8311610606576020808501948460051b01011161060657565b6003196060910112610606576001600160a01b03600435818116810361060657916024359160443590811681036106065790565b6080600319820112610606576001600160a01b0391600435838116810361060657926024359081168103610606579167ffffffffffffffff916044358381116106065782612f7191600401612ebc565b9390939260643591821161060657612f8b91600401612bca565b9091565b9190811015612fcf5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc181360301821215610606570190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116106065760209260051b809284830137010190565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016301461306d57565b60046040517fbbff6135000000000000000000000000000000000000000000000000000000008152fd5b919082039182116130a457565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000060208201526001600160a01b0392909216602483015260448083019390935291815261312d91613128606483612cad565b613147565b565b90816020910312610606575180151581036106065790565b6040516131a5916001600160a01b031661316082612c75565b6000806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af161319f61325a565b916132b8565b805190828215928315613242575b505050156131be5750565b608490604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152fd5b613252935082018101910161312f565b3882816131b3565b3d156132b3573d9067ffffffffffffffff8211612c0c57604051916132a760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612cad565b82523d6000602084013e565b606090565b9192901561333357508151156132cc575090565b3b156132d55790565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156133465750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b8481106133c3575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b818101830151868201604401528593508201613382565b9190811015612fcf57610120020190565b356fffffffffffffffffffffffffffffffff811681036106065790565b9061341282612db0565b61341f6040519182612cad565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061344d8294612db0565b0190602036910137565b3580151581036106065790565b356001600160a01b03811681036106065790565b61312d9092919261010060e06101408301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151602064ffffffffff918281511660c0880152015116828501520151910190602080916001600160a01b0381511684520151910152565b8051821015612fcf5760209160051b010190565b9190811015612fcf57610140020190565b61312d9092919261012060e06101608301956001600160a01b038082511685528060208301511660208601526fffffffffffffffffffffffffffffffff6040830151166040860152606082015116606085015260808101511515608085015260a0810151151560a085015260c0810151604064ffffffffff918281511660c088015282602082015116858801520151166101008501520151910190602080916001600160a01b0381511684520151910152565b602080916001600160a01b0361360b82612ba0565b1684520135910152565b9190811015612fcf5760051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0181360301821215610606570190565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610606570180359067ffffffffffffffff82116106065760200191606082023603831361060657565b9060208083526101408301908061016060e06001600160a01b0395868151168489015283810151151560408901526040810151966060971515888a015280888301511660808a01526fffffffffffffffffffffffffffffffff60808301511660a08a015260a08201511660c089015261373c60c0820151838a0190602080916001600160a01b0381511684520151910152565b015195610120808201528651809552019401926000905b83821061376257505050505090565b90919293948382826137ae6001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b0196019493920190613753565b9190811015612fcf5760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee181360301821215610606570190565b906020808352610160830190806101806001600160a01b0394858151168388015264ffffffffff8382015116604088015260408101519560609615158789015286820151151560808901528060808301511660a08901526fffffffffffffffffffffffffffffffff60a08301511660c089015260c08201511660e088015260e0810151906138a261010092838a0190602080916001600160a01b0381511684520151910152565b015195610140808201528651809552019401926000905b8382106138c857505050505090565b90919293948382826139146001948a5164ffffffffff604080926fffffffffffffffffffffffffffffffff815116855267ffffffffffffffff6020820151166020860152015116910152565b01960194939201906138b9565b613a0b9061392d61303b565b60a08301906001600160a01b0390811661394683613464565b608086016139716fffffffffffffffffffffffffffffffff9283613969846133eb565b169085613ce5565b613a2c6040519788957f1684445600000000000000000000000000000000000000000000000000000000875260209889988960048a0152610144890196836139b886612ba0565b1660248b01526139c98b8601612d22565b151560448b01526139dc60408601612d22565b151560648b0152613a00606097856139f58a8901612ba0565b1660848d0152612d4e565b1660a48a0152612ba0565b1660c4870152613a2160e4870160c083016135f6565b610100810190613abf565b809193610120610124880152526101648501929160005b828110613a985750505050600083809203925af1908115610cfc57600091613a6c575b50905090565b82813d8311613a91575b613a808183612cad565b8101031261023c5750518038613a66565b503d613a76565b9295506001919496508084613aae829689613b12565b019501910192879492879694613a43565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561060657016020813591019167ffffffffffffffff821161060657606082023603831361060657565b64ffffffffff613b5d604080936fffffffffffffffffffffffffffffffff613b3982612d4e565b16865267ffffffffffffffff613b5160208301612dc8565b16602087015201612ddd565b16910152565b613c5d90613b6f61303b565b60c08301906001600160a01b03908116613b8883613464565b60a08601613bab6fffffffffffffffffffffffffffffffff9283613969846133eb565b613c7f6040519788957fc33cd35e00000000000000000000000000000000000000000000000000000000875260209889988960048a015261016489019683613bf286612ba0565b1660248b015264ffffffffff613c098c8701612ddd565b1660448b0152613c1b60408601612d22565b151560648b0152613c52606097613c33898801612d22565b151560848d015285613c4760808901612ba0565b1660a48d0152612d4e565b1660c48a0152612ba0565b1660e4870152613c74610104870160e083016135f6565b610120810190613abf565b809193610140610144880152526101848501929160005b828110613cbe5750505050600083809203925af1908115610cfc57600091613a6c5750905090565b9295506001919496508084613cd4829689613b12565b019501910192879492879694613c96565b91906001600160a01b039283821690604051947fdd62ed3e0000000000000000000000000000000000000000000000000000000086523060048701528116918260248701526020958681604481855afa8015610cfc578691600091613e87575b5010613d54575b505050505050565b60008060405196613dd688613daa8b8201937f095ea7b3000000000000000000000000000000000000000000000000000000009889865260248401602090939291936001600160a01b0360408201951681520152565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018a5289612cad565b87519082855af190613de661325a565b82613e54575b5081613e49575b5015613e00575b80613d4c565b60405194850152602484015260006044840152604483526080830183811067ffffffffffffffff821117612c0c57613e3f936131289160405282613147565b3880808080613dfa565b90503b151538613df3565b809192505190878215928315613e6f575b5050509038613dec565b613e7f935082018101910161312f565b388781613e65565b91508782813d8311613eb0575b613e9e8183612cad565b8101031261023c575085905138613d45565b503d613e94565b9190811015612fcf5760051b0190565b919091613ed383613408565b9260005b818110613ee357505050565b6001600160a01b03613ef9610974838587613eb7565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa918215613f8b5750600091613f5a575b5060019250613f53828861351e565b5201613ed7565b919282813d8311613f84575b613f708183612cad565b8101031261023c5750906001915138613f44565b503d613f66565b513d6000823e3d90fd5b6040517f8da5cb5b000000000000000000000000000000000000000000000000000000008152602081600481305afa908115610cfc57600091613fd6575090565b6020813d821161400c575b81613fee60209383612cad565b8101031261089d5751906001600160a01b038216820361023c575090565b3d9150613fe1565b909160005b8181106140265750505050565b6001600160a01b0361403c610974838588613eb7565b16906040805180937f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209687935afa918215613f8b57506000916140c0575b50600192506140a46140ba9161409d848861351e565b5190613097565b6140b261097484878a613eb7565b6107bf613f95565b01614019565b919282813d83116140ec575b6140d68183612cad565b8101031261023c575051600191906140a4614087565b503d6140cc565b6001600160a01b031660409081517f70a08231000000000000000000000000000000000000000000000000000000008082526000903060048401526020908184602481885afa93841561427e57839461424f575b50843b156104355785517fd0e30db00000000000000000000000000000000000000000000000000000000081528381600481348a5af1801561424557614232575b508190602487518097819382523060048301525afa91821561422757916141f7575b506141b59250613097565b903482036141c1575050565b6044925051907fe5f762580000000000000000000000000000000000000000000000000000000082523460048301526024820152fd5b905082813d8311614220575b61420d8183612cad565b81010312610606576141b59151386141aa565b503d614203565b8551903d90823e3d90fd5b9261423e839294612bf8565b9290614188565b87513d86823e3d90fd5b9093508181813d8311614277575b6142678183612cad565b8101031261043557519238614147565b503d61425d565b86513d85823e3d90fdfea164736f6c6343000815000a"; /*////////////////////////////////////////////////////////////////////////// DEPLOYERS @@ -49,66 +40,15 @@ contract Precompiles { ); } - /// @notice Deploys {SablierV2ProxyTargetApprove} from precompiled bytecode. - function deployProxyTargetApprove() public returns (ISablierV2ProxyTarget proxyTargetApprove) { - bytes memory creationBytecode = BYTECODE_PROXY_TARGET_APPROVE; - assembly { - proxyTargetApprove := create(0, add(creationBytecode, 0x20), mload(creationBytecode)) - } - require( - address(proxyTargetApprove) != address(0), - "Sablier V2 Precompiles: deployment failed for ProxyTargetApprove contract" - ); - } - - /// @notice Deploys {SablierV2ProxyTargetPermit2} from precompiled bytecode. - function deployProxyTargetPermit2(IAllowanceTransfer permit2) - public - returns (ISablierV2ProxyTarget proxyTargetPermit2) - { - bytes memory creationBytecode = bytes.concat(BYTECODE_PROXY_TARGET_PERMIT2, abi.encode(permit2)); - assembly { - proxyTargetPermit2 := create(0, add(creationBytecode, 0x20), mload(creationBytecode)) - } - require( - address(proxyTargetPermit2) != address(0), - "Sablier V2 Precompiles: deployment failed for ProxyTargetPermit2 contract" - ); - } - - /// @notice Deploys {SablierV2ProxyTargetPush} from precompiled bytecode. - function deployProxyTargetPush() public returns (ISablierV2ProxyTarget proxyTargetPush) { - bytes memory creationBytecode = BYTECODE_PROXY_TARGET_PUSH; - assembly { - proxyTargetPush := create(0, add(creationBytecode, 0x20), mload(creationBytecode)) - } - require( - address(proxyTargetPush) != address(0), - "Sablier V2 Precompiles: deployment failed for ProxyTargetPush contract" - ); - } - /// @notice Deploys all V2 Periphery contracts in the following order: /// /// 1. {SablierV2Batch} /// 2. {SablierV2MerkleStreamerFactory} - /// 3. {SablierV2ProxyTargetApprove} - /// 4. {SablierV2ProxyTargetPermit2} - /// 5. {SablierV2ProxyTargetPush} - function deployPeriphery(IAllowanceTransfer permit2) + function deployPeriphery() public - returns ( - ISablierV2Batch batch, - ISablierV2MerkleStreamerFactory merkleStreamerFactory, - ISablierV2ProxyTarget proxyTargetApprove, - ISablierV2ProxyTarget proxyTargetPermit2, - ISablierV2ProxyTarget proxyTargetPush - ) + returns (ISablierV2Batch batch, ISablierV2MerkleStreamerFactory merkleStreamerFactory) { batch = deployBatch(); merkleStreamerFactory = deployMerkleStreamerFactory(); - proxyTargetApprove = deployProxyTargetApprove(); - proxyTargetPermit2 = deployProxyTargetPermit2(permit2); - proxyTargetPush = deployProxyTargetPush(); } } diff --git a/test/utils/Precompiles.t.sol b/test/utils/Precompiles.t.sol index abb50eef..4d61f24a 100644 --- a/test/utils/Precompiles.t.sol +++ b/test/utils/Precompiles.t.sol @@ -1,13 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.19 <0.9.0; -import { IAllowanceTransfer } from "@uniswap/permit2/interfaces/IAllowanceTransfer.sol"; -import { DeployPermit2 } from "@uniswap/permit2-test/utils/DeployPermit2.sol"; import { LibString } from "solady/utils/LibString.sol"; import { ISablierV2Batch } from "../../src/interfaces/ISablierV2Batch.sol"; import { ISablierV2MerkleStreamerFactory } from "../../src/interfaces/ISablierV2MerkleStreamerFactory.sol"; -import { ISablierV2ProxyTarget } from "../../src/interfaces/ISablierV2ProxyTarget.sol"; import { Base_Test } from "../Base.t.sol"; import { Precompiles } from "./Precompiles.sol"; @@ -36,115 +33,16 @@ contract Precompiles_Test is Base_Test { assertEq(actualFactory.code, expectedFactory.code, "bytecodes mismatch"); } - function test_DeployProxyTargetApprove() external onlyTestOptimizedProfile { - address actualProxyTargetApprove = address(precompiles.deployProxyTargetApprove()); - address expectedProxyTargetApprove = address(deployOptimizedProxyTargetApprove()); - bytes memory expectedProxyTargetCode = - adjustBytecode(expectedProxyTargetApprove.code, expectedProxyTargetApprove, actualProxyTargetApprove); - assertEq(actualProxyTargetApprove.code, expectedProxyTargetCode, "bytecodes mismatch"); - } - - function test_DeployProxyTargetPermit2() external onlyTestOptimizedProfile { - IAllowanceTransfer permit2 = IAllowanceTransfer(new DeployPermit2().run()); - address actualProxyTargetPermit2 = address(precompiles.deployProxyTargetPermit2(permit2)); - address expectedProxyTargetPermit2 = address(deployOptimizedProxyTargetPermit2(permit2)); - bytes memory expectedProxyTargetCode = - adjustBytecode(expectedProxyTargetPermit2.code, expectedProxyTargetPermit2, actualProxyTargetPermit2); - assertEq(actualProxyTargetPermit2.code, expectedProxyTargetCode, "bytecodes mismatch"); - } - - function test_DeployProxyTargetPush() external onlyTestOptimizedProfile { - address actualProxyTargetPush = address(precompiles.deployProxyTargetPush()); - address expectedProxyTargetPush = address(deployOptimizedProxyTargetPush()); - bytes memory expectedProxyTargetCode = - adjustBytecode(expectedProxyTargetPush.code, expectedProxyTargetPush, actualProxyTargetPush); - assertEq(actualProxyTargetPush.code, expectedProxyTargetCode, "bytecodes mismatch"); - } - - /// @dev Needed to prevent "Stack too deep" error - struct Vars { - IAllowanceTransfer permit2; - ISablierV2Batch actualBatch; - ISablierV2MerkleStreamerFactory actualMerkleStreamerFactory; - ISablierV2ProxyTarget actualProxyTargetApprove; - ISablierV2ProxyTarget actualProxyTargetPermit2; - ISablierV2ProxyTarget actualProxyTargetPush; - ISablierV2Batch expectedBatch; - ISablierV2MerkleStreamerFactory expectedMerkleStreamerFactory; - ISablierV2ProxyTarget expectedProxyTargetApprove; - bytes expectedProxyTargetApproveCode; - ISablierV2ProxyTarget expectedProxyTargetPermit2; - bytes expectedProxyTargetPermit2Code; - ISablierV2ProxyTarget expectedProxyTargetPush; - bytes expectedProxyTargetPushCode; - } - function test_DeployPeriphery() external onlyTestOptimizedProfile { - Vars memory vars; + (ISablierV2Batch actualBatch, ISablierV2MerkleStreamerFactory actualMerkleStreamerFactory) = + precompiles.deployPeriphery(); - vars.permit2 = IAllowanceTransfer(new DeployPermit2().run()); - ( - vars.actualBatch, - vars.actualMerkleStreamerFactory, - vars.actualProxyTargetApprove, - vars.actualProxyTargetPermit2, - vars.actualProxyTargetPush - ) = precompiles.deployPeriphery(permit2); + (ISablierV2Batch expectedBatch, ISablierV2MerkleStreamerFactory expectedMerkleStreamerFactory) = + deployOptimizedPeriphery(); - ( - vars.expectedBatch, - vars.expectedMerkleStreamerFactory, - vars.expectedProxyTargetApprove, - vars.expectedProxyTargetPermit2, - vars.expectedProxyTargetPush - ) = deployOptimizedPeriphery(permit2); - - assertEq(address(vars.actualBatch).code, address(vars.expectedBatch).code, "bytecodes mismatch"); + assertEq(address(actualBatch).code, address(expectedBatch).code, "bytecodes mismatch"); assertEq( - address(vars.actualMerkleStreamerFactory).code, - address(vars.expectedMerkleStreamerFactory).code, - "bytecodes mismatch" - ); - - vars.expectedProxyTargetApproveCode = adjustBytecode( - address(vars.expectedProxyTargetApprove).code, - address(vars.expectedProxyTargetApprove), - address(vars.actualProxyTargetApprove) - ); - - vars.expectedProxyTargetPermit2Code = adjustBytecode( - address(vars.expectedProxyTargetPermit2).code, - address(vars.expectedProxyTargetPermit2), - address(vars.actualProxyTargetPermit2) - ); - - vars.expectedProxyTargetPushCode = adjustBytecode( - address(vars.expectedProxyTargetPush).code, - address(vars.expectedProxyTargetPush), - address(vars.actualProxyTargetPush) - ); - - assertEq(address(vars.actualProxyTargetApprove).code, vars.expectedProxyTargetApproveCode, "bytecodes mismatch"); - assertEq(address(vars.actualProxyTargetPermit2).code, vars.expectedProxyTargetPermit2Code, "bytecodes mismatch"); - assertEq(address(vars.actualProxyTargetPush).code, vars.expectedProxyTargetPushCode, "bytecodes mismatch"); - } - - /// @dev The expected bytecode has to be adjusted because some contracts inherit from {OnlyDelegateCall}, which - /// saves the contract's own address in storage. - function adjustBytecode( - bytes memory bytecode, - address expectedAddress, - address actualAddress - ) - internal - pure - returns (bytes memory) - { - return vm.parseBytes( - vm.toString(bytecode).replace({ - search: expectedAddress.toHexStringNoPrefix(), - replacement: actualAddress.toHexStringNoPrefix() - }) + address(actualMerkleStreamerFactory).code, address(expectedMerkleStreamerFactory).code, "bytecodes mismatch" ); } } diff --git a/test/utils/Types.sol b/test/utils/Types.sol index 2f5b1c96..d722cd61 100644 --- a/test/utils/Types.sol +++ b/test/utils/Types.sol @@ -1,16 +1,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.19 <0.9.0; -import { StdCheats } from "forge-std/StdCheats.sol"; - struct Users { - StdCheats.Account alice; - StdCheats.Account admin; - StdCheats.Account broker; - StdCheats.Account eve; - StdCheats.Account recipient0; - StdCheats.Account recipient1; - StdCheats.Account recipient2; - StdCheats.Account recipient3; - StdCheats.Account recipient4; + address alice; + address admin; + address broker; + address eve; + address recipient0; + address recipient1; + address recipient2; + address recipient3; + address recipient4; }