Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Foundry #69

Draft
wants to merge 5 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ cache
artifacts
dist/
test/workspace.code-workspace
tenderly.yaml
tenderly.yaml

# Foundry
cache/
out/

3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std/
2 changes: 1 addition & 1 deletion contracts/AutomationBot.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

/// MultiplyProxyActions.sol
/// AutomationBot.sol

// Copyright (C) 2021-2021 Oazo Apps Limited

Expand Down
11 changes: 11 additions & 0 deletions contracts/interfaces/IDssProxyActions.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

interface IDssProxyActions {
function cdpAllow(
address manager,
uint256 cdp,
address usr,
uint256 ok
) external;
}
4 changes: 0 additions & 4 deletions contracts/tests/DummyCommand.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@ pragma solidity ^0.8.0;

import "../interfaces/ICommand.sol";
import "../interfaces/BotLike.sol";
import "../ServiceRegistry.sol";

contract DummyCommand is ICommand {
address public serviceRegistry;
bool public initialCheckReturn;
bool public finalCheckReturn;
bool public revertsInExecute;
bool public validTriggerData;

constructor(
address _serviceRegistry,
bool _initialCheckReturn,
bool _finalCheckReturn,
bool _revertsInExecute,
bool _validTriggerData
) {
serviceRegistry = _serviceRegistry;
initialCheckReturn = _initialCheckReturn;
finalCheckReturn = _finalCheckReturn;
revertsInExecute = _revertsInExecute;
Expand Down
12 changes: 1 addition & 11 deletions contracts/tests/DummyRollingCommand.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,18 @@ pragma solidity ^0.8.0;

import "../interfaces/ICommand.sol";
import "../interfaces/BotLike.sol";
import "../ServiceRegistry.sol";
import "../AutomationBot.sol";
import { DummyCommand } from "../tests/DummyCommand.sol";

contract DummyRollingCommand is DummyCommand {
uint256 public immutable triggerType;

constructor(
address _serviceRegistry,
bool _initialCheckReturn,
bool _finalCheckReturn,
bool _revertsInExecute,
bool _validTriggerData
)
DummyCommand(
_serviceRegistry,
_initialCheckReturn,
_finalCheckReturn,
_revertsInExecute,
_validTriggerData
)
{
) DummyCommand(_initialCheckReturn, _finalCheckReturn, _revertsInExecute, _validTriggerData) {
triggerType = 100;
}

Expand Down
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[default]
test = "test_"
1 change: 1 addition & 0 deletions lib/forge-std
Submodule forge-std added at 564510
61 changes: 61 additions & 0 deletions scripts_/System.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
pragma solidity ^0.8.0;

// import "forge-std/Script.sol";
import { Script } from "../lib/forge-std/src/Script.sol";
import { console } from "../lib/forge-std/src/console.sol";

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ServiceRegistry } from "../contracts/ServiceRegistry.sol";
import { AutomationBot } from "../contracts/AutomationBot.sol";
import { AutomationExecutor } from "../contracts/AutomationExecutor.sol";
import { McdUtils } from "../contracts/McdUtils.sol";
import { BotLike } from "../contracts/interfaces/BotLike.sol";
import { ManagerLike } from "../contracts/interfaces/ManagerLike.sol";
import { IWETH } from "../contracts/interfaces/IWETH.sol";
import { AddressesMainnet } from "../scripts__/AddressesMainnet.sol";
import { AddressesGoerli } from "../scripts__/AddressesGoerli.sol";

function bytesToAddress(bytes memory bys) pure returns (address addr) {
assembly {
addr := mload(add(bys, 20))
}
}

contract System is Script {
ManagerLike public immutable manager = ManagerLike(AddressesMainnet.CDP_MANAGER);

ServiceRegistry public immutable registry;
AutomationBot public immutable bot;
AutomationExecutor public immutable executor;
McdUtils public immutable mcdUtils;

// McdView public immutable mcdView;

constructor(uint256 delay) {
registry = new ServiceRegistry(delay);
bot = new AutomationBot(registry);
executor = new AutomationExecutor(
BotLike(address(bot)),
IERC20(AddressesMainnet.DAI),
IWETH(AddressesMainnet.WETH),
AddressesMainnet.EXCHANGE
);
mcdUtils = new McdUtils(
address(registry),
IERC20(AddressesMainnet.DAI),
AddressesMainnet.DAI_JOIN,
AddressesMainnet.MCD_JUG
);

// TODO: if delay > 0
registry.addNamedService(
keccak256(abi.encodePacked("CDP_MANAGER")),
AddressesMainnet.CDP_MANAGER
);
registry.addNamedService(keccak256(abi.encodePacked("AUTOMATION_BOT")), address(bot));

// TODO: can i delegatecall constructor?
registry.transferOwnership(msg.sender);
executor.transferOwnership(msg.sender);
}
}
27 changes: 27 additions & 0 deletions scripts__/AddressesGoerli.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.8.0;

library AddressesGoerli {
address public constant CDP_MANAGER = 0xdcBf58c9640A7bd0e062f8092d70fb981Bb52032;
address public constant ILK_REGISTRY = 0x525FaC4CEc48a4eF2FBb0A72355B6255f8D5f79e;
address public constant MCD_VAT = 0xB966002DDAa2Baf48369f5015329750019736031;
address public constant MCD_JUG = 0xC90C99FE9B5d5207A03b9F28A6E8A19C0e558916;
address public constant OSM_MOM = 0xEdB6b497D2e18A33130CB0D2b70343E6Dcd9EE86;
address public constant MCD_SPOT = 0xACe2A9106ec175bd56ec05C9E38FE1FDa8a1d758;
address public constant MCD_JOIN_ETH_A = 0x2372031bB0fC735722AA4009AeBf66E8BEAF4BA1;
address public constant MCD_FLASH = 0x0a6861D6200B519a8B9CFA1E7Edd582DD1573581;
address public constant PROXY_REGISTRY = 0x46759093D8158db8BB555aC7C6F98070c56169ce;
address public constant WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;
address public constant DAI = 0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844;
address public constant DAI_JOIN = 0x6a60b7070befb2bfc964F646efDF70388320f4E0;
address public constant DSS_PROXY_ACTIONS = address(0);
address public constant MULTIPLY_PROXY_ACTIONS = 0xc9628adc0a9f95D1d912C5C19aaBFF85E420a853;
address public constant ZERO_FEE_EXCHANGE = address(0);
address public constant EXCHANGE = 0x1F55deAeE5e878e45dcafb9A620b383C84e4005a;
address public constant AUTOMATION_SERVICE_REGISTRY =
0x5A5277B8c8a42e6d8Ab517483D7D59b4ca03dB7F;
address public constant AUTOMATION_BOT = 0xabDB63B4b3BA9f960CF942800a6982F88e9b1A6b;
address public constant AUTOMATION_EXECUTOR = 0x7C0d6D8D6EAe8bcb106aFDb3a21Df5C254C6c0b2;
address public constant AUTOMATION_MCD_VIEW = 0xb0724B07883DF9e9276a77CD73acd00FE5F86F55;
address public constant AUTOMATION_MCD_UTILS = 0xc27F0A5e6c6f2819d953eE04F2FABdF680D5130c;
address public constant AUTOMATION_CLOSE_COMMAND = 0x31285A87fB70a62b5AaA43199e53221c197E1e3f;
}
27 changes: 27 additions & 0 deletions scripts__/AddressesMainnet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.8.0;

library AddressesMainnet {
address public constant CDP_MANAGER = 0x5ef30b9986345249bc32d8928B7ee64DE9435E39;
address public constant ILK_REGISTRY = 0x5a464C28D19848f44199D003BeF5ecc87d090F87;
address public constant MCD_VAT = 0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B;
address public constant MCD_JUG = 0x19c0976f590D67707E62397C87829d896Dc0f1F1;
address public constant OSM_MOM = 0x76416A4d5190d071bfed309861527431304aA14f;
address public constant MCD_SPOT = 0x65C79fcB50Ca1594B025960e539eD7A9a6D434A3;
address public constant MCD_JOIN_ETH_A = 0x2F0b23f53734252Bda2277357e97e1517d6B042A;
address public constant MCD_FLASH = 0x1EB4CF3A948E7D72A198fe073cCb8C7a948cD853;
address public constant PROXY_REGISTRY = 0x4678f0a6958e4D2Bc4F1BAF7Bc52E8F3564f3fE4;
address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address public constant DAI_JOIN = 0x9759A6Ac90977b93B58547b4A71c78317f391A28;
address public constant DSS_PROXY_ACTIONS = 0x82ecD135Dce65Fbc6DbdD0e4237E0AF93FFD5038;
address public constant MULTIPLY_PROXY_ACTIONS = 0x2a49Eae5CCa3f050eBEC729Cf90CC910fADAf7A2;
address public constant ZERO_FEE_EXCHANGE = 0x99E4484Dac819aA74B347208752306615213d324;
address public constant EXCHANGE = 0xb5eB8cB6cED6b6f8E13bcD502fb489Db4a726C7B;
address public constant AUTOMATION_SERVICE_REGISTRY =
0x9b4Ae7b164d195df9C4Da5d08Be88b2848b2EaDA;
address public constant AUTOMATION_BOT = 0x6E87a7A0A03E51A741075fDf4D1FCce39a4Df01b;
address public constant AUTOMATION_EXECUTOR = 0x40A63b453502ab04DfDf86fB79a9FF2Ec337E188;
address public constant AUTOMATION_MCD_VIEW = 0x55Dc2Be8020bCa72E58e665dC931E03B749ea5E0;
address public constant AUTOMATION_MCD_UTILS = 0x68Ff2d96EDD4aFfcE9CBE82BF55F0B70acb483Ea;
address public constant AUTOMATION_CLOSE_COMMAND = 0xa553c3f4e65A1FC951B236142C1f69c1BcA5bF2b;
}
25 changes: 15 additions & 10 deletions test/automation-bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,8 @@ describe('AutomationBot', async () => {

const system = await deploySystem({ utils, addCommands: false })

DummyCommandInstance = (await dummyCommandFactory.deploy(
system.serviceRegistry.address,
true,
true,
false,
true,
)) as DummyCommand
DummyCommandInstance = (await dummyCommandFactory.deploy(true, true, false, true)) as DummyCommand
DummyRollingCommandInstance = (await dummyRollingCommandFactory.deploy(
system.serviceRegistry.address,
true,
true,
false,
Expand Down Expand Up @@ -77,8 +70,19 @@ describe('AutomationBot', async () => {
cdpId: number,
operator: string,
allow: number,
) =>
proxy
) => {
console.log(
proxy.interface.encodeFunctionData('execute', [
DssProxyActions.address,
DssProxyActions.interface.encodeFunctionData('cdpAllow', [
hardhatUtils.addresses.CDP_MANAGER,
cdpId,
operator,
allow,
]),
]),
)
return proxy
.connect(signer)
.execute(
DssProxyActions.address,
Expand All @@ -89,6 +93,7 @@ describe('AutomationBot', async () => {
allow,
]),
)
}

beforeEach(async () => {
snapshotId = await hre.ethers.provider.send('evm_snapshot', [])
Expand Down
8 changes: 1 addition & 7 deletions test/automation-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,7 @@ describe('AutomationExecutor', async () => {
])

const dummyCommandFactory = await hre.ethers.getContractFactory('DummyCommand')
DummyCommandInstance = await dummyCommandFactory.deploy(
ServiceRegistryInstance.address,
true,
true,
false,
true,
)
DummyCommandInstance = await dummyCommandFactory.deploy(true, true, false, true)
DummyCommandInstance = await DummyCommandInstance.deployed()

let hash = getCommandHash(TriggerType.CLOSE_TO_DAI)
Expand Down
17 changes: 5 additions & 12 deletions test/service-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ describe('ServiceRegistry', async () => {
})

it('should fail if called for a second time immediately', async () => {
const notOwnerTrustedRegistryInstance = trustedRegistryInstance.connect(owner)
await notOwnerTrustedRegistryInstance.transferOwnership(await notOwner.getAddress())
const tx2 = notOwnerTrustedRegistryInstance.transferOwnership(await notOwner.getAddress())
const instance = trustedRegistryInstance.connect(owner)
await instance.transferOwnership(await notOwner.getAddress())
const tx2 = instance.transferOwnership(await notOwner.getAddress())
await expect(tx2).to.be.revertedWith('delay-too-small')
})

Expand All @@ -78,13 +78,6 @@ describe('ServiceRegistry', async () => {
expect(txResult.events ? txResult.events[0].event : 'null').to.be.equal('ChangeScheduled')
})

it('should fail if called for a second time immediately', async () => {
const instance = trustedRegistryInstance.connect(owner)
await instance.transferOwnership(await notOwner.getAddress())
const tx2 = instance.transferOwnership(await notOwner.getAddress())
await expect(tx2).to.be.revertedWith('delay-too-small')
})

it('should fail if called for a second time after too short delay', async () => {
const instance = trustedRegistryInstance.connect(owner)
await instance.transferOwnership(await notOwner.getAddress())
Expand Down Expand Up @@ -224,8 +217,8 @@ describe('ServiceRegistry', async () => {
it('should have no effect if called once', async () => {
const instance = trustedRegistryInstance.connect(owner)
await instance.addNamedService(supposedHash, await notOwner.getAddress())
const newOwnerAddress = await instance.getServiceAddress(supposedHash)
expect(newOwnerAddress).to.be.equal('0x0000000000000000000000000000000000000000')
const serviceAddress = await instance.getServiceAddress(supposedHash)
expect(serviceAddress).to.be.equal('0x0000000000000000000000000000000000000000')
})

it('should emit ChangeScheduled if called once', async () => {
Expand Down
Loading