Skip to content

Commit

Permalink
chore: refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
kostyamospan committed May 29, 2024
1 parent c7d1351 commit 9811ce0
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 92 deletions.
61 changes: 54 additions & 7 deletions contracts/SmartWalletFactoryV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,69 @@
pragma solidity ^0.8.23;

import "@openzeppelin/contracts/proxy/Clones.sol";
import "./interfaces/ISmartWalletFactory.sol";
import "./SmartWalletV1.sol";
import "./structs/CreateWalletParams.sol";

contract SmartWalletFactoryV1 {
contract SmartWalletFactoryV1 is ISmartWalletFactory {
address public immutable implementation;

mapping(address => bytes32) public deployedSalts;

CommonDeployParams public commonDeployParams;
uint256 public counter;

constructor(address _implementation) {
struct CommonDeployParams {
address linkToken;
address clRegistrar;
address clRegistry;
address uniswapV3Router;
address wethToken;
bytes wethToLinkSwapPath;
}

constructor(
CommonDeployParams memory _commonDeployParams,
address _implementation
) {
implementation = _implementation;
commonDeployParams = _commonDeployParams;
}

function createWallet(
CreateWalletParams calldata params
address owner,
address allowlistOperator
) external returns (address) {
return create2Wallet(params, keccak256(abi.encodePacked(counter++)));
return
create2Wallet(
owner,
allowlistOperator,
keccak256(abi.encodePacked(counter++))
);
}

function create2Wallet(
CreateWalletParams calldata params,
address owner,
address allowlistOperator,
bytes32 salt
) public returns (address) {
SmartWalletV1 wallet = SmartWalletV1(
payable(Clones.cloneDeterministic(implementation, salt))
);
wallet.initialize(params);
wallet.initialize(
CreateWalletParams({
owner: owner,
allowlistOperator: allowlistOperator,
linkToken: commonDeployParams.linkToken,
clRegistrar: commonDeployParams.clRegistrar,
clRegistry: commonDeployParams.clRegistry,
uniswapV3Router: commonDeployParams.uniswapV3Router,
wethToken: commonDeployParams.wethToken,
wethToLinkSwapPath: commonDeployParams.wethToLinkSwapPath
})
);

deployedSalts[address(wallet)] = salt;

return address(wallet);
}

Expand All @@ -40,4 +78,13 @@ contract SmartWalletFactoryV1 {
address(this)
);
}

function validateWallet(address wallet) external view returns (bool) {
address expectedAddress = Clones.predictDeterministicAddress(
implementation,
deployedSalts[wallet],
address(this)
);
return expectedAddress == wallet;
}
}
113 changes: 63 additions & 50 deletions contracts/SmartWalletV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable
import "@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Address.sol";
// import "@chainlink/contracts/src/v0.8/.sol";
import "./libraries/EnumerableMap.sol";
import "./libraries/UniswapV3Actions.sol";
import "./interfaces/IWeth.sol";
import "./interfaces/IAutoExecuteCallback.sol";
import "./interfaces/IAutomationRegistrarInterface.sol";
import "./interfaces/IAutomationRegistryInterface.sol";
import "./structs/CreateWalletParams.sol";
import "./interfaces/ISmartWallet.sol";
import "./interfaces/ISmartWalletFactory.sol";

import "hardhat/console.sol";

contract SmartWalletV1 is
OwnableUpgradeable,
EIP712Upgradeable,
NoncesUpgradeable
NoncesUpgradeable,
ISmartWallet
{
using EnumerableMap for EnumerableMap.UintToAutoExecuteMap;
using Address for address;
Expand All @@ -36,19 +38,20 @@ contract SmartWalletV1 is

mapping(address => bool) public allowlist;
mapping(address => mapping(bytes4 => bool)) public blacklistedFunctions;
EnumerableMap.UintToAutoExecuteMap autoExecutesMap;
address public allowListOperator;

address public linkToken;
address public clRegistrar;
address public clRegistry;
address public allowListOperator;
uint256 public autoExecuteCounter;
uint256 public upkeepId;

address public uniswapV3Router;
address public wethToken;
bytes public wethToLinkSwapPath;
address private linkToken;
address private clRegistrar;
address private clRegistry;

uint256 public autoExecuteCounter;
EnumerableMap.UintToAutoExecuteMap private autoExecutesMap;

address private uniswapV3Router;
address private wethToken;
bytes private wethToLinkSwapPath;

modifier onlyAllowlist() {
require(allowlist[msg.sender], "SW: not in allowlist");
Expand All @@ -67,7 +70,7 @@ contract SmartWalletV1 is
receive() external payable {}

function initialize(
CreateWalletParams calldata createParams
ISmartWalletFactory.CreateWalletParams calldata createParams
) external initializer {
__Ownable_init(createParams.owner);
__EIP712_init("SmartWalletV1", "1");
Expand All @@ -80,13 +83,45 @@ contract SmartWalletV1 is
linkToken = createParams.linkToken;
clRegistrar = createParams.clRegistrar;
clRegistry = createParams.clRegistry;
}

for (uint i; i < createParams.initAllowlist.length; i++) {
allowlist[createParams.initAllowlist[i]] = true;
function execute(
address to,
uint256 callValue,
bytes calldata data
) public onlyOwner returns (bytes memory returnData) {
require(to != address(this), "SW: to cannot be this");
returnData = _execute(to, callValue, data);
}

function executeBatch(
address[] calldata tos,
uint256[] calldata callValues,
bytes[] calldata datas
) public onlyOwner returns (bytes[] memory returnDatas) {
require(
tos.length == callValues.length && tos.length == datas.length,
"SW: mismatch arrays"
);
returnDatas = new bytes[](tos.length);
for (uint i = 0; i < tos.length; i++) {
returnDatas[i] = _execute(tos[i], callValues[i], datas[i]);
}
}

function blacklist(
function blacklist(address to, bytes4 funcSelector) external onlyAllowlist {
require(funcSelector != bytes4(0), "SW: invalid selector");
blacklistedFunctions[to][funcSelector] = true;
}

function removeFromBlacklist(
address to,
bytes4 funcSelector
) external onlyAllowlist {
blacklistedFunctions[to][funcSelector] = false;
}

function blacklistBatch(
address[] calldata tos,
bytes4[] calldata funcSelectors
) external onlyAllowlist {
Expand All @@ -97,7 +132,7 @@ contract SmartWalletV1 is
}
}

function removeFromBlacklist(
function removeFromBlacklistBatch(
address[] calldata tos,
bytes4[] calldata funcSelectors
) external onlyAllowlist {
Expand Down Expand Up @@ -171,29 +206,13 @@ contract SmartWalletV1 is
allowlist[addr] = false;
}

function execute(
address to,
uint256 callValue,
bytes calldata data
) public onlyOwner returns (bytes memory returnData) {
require(to != address(this), "SW: to cannot be this");
returnData = _execute(to, callValue, data);
}
function performUpkeep(bytes calldata performData) external {
uint256 id = abi.decode(performData, (uint256));
AutoExecute memory data = autoExecutesMap.get(id);
require(block.timestamp > data.executeAfter, "SW: to early to execute");

function executeBatch(
address[] calldata tos,
uint256[] calldata callValues,
bytes[] calldata datas
) public onlyOwner returns (bytes[] memory returnDatas) {
require(
tos.length == callValues.length && tos.length == datas.length,
"SW: mismatch arrays"
);
returnDatas = new bytes[](tos.length);
for (uint i = 0; i < tos.length; i++) {
require(tos[i] != address(this), "SW: to cannot be this");
returnDatas[i] = _execute(tos[i], callValues[i], datas[i]);
}
_executeUpkeep(data);
autoExecutesMap.remove(id);
}

function checkUpkeep(
Expand All @@ -210,23 +229,17 @@ contract SmartWalletV1 is
}
}

function performUpkeep(bytes calldata performData) external {
uint256 id = abi.decode(performData, (uint256));
AutoExecute memory data = autoExecutesMap.get(id);
require(block.timestamp > data.executeAfter, "SW: to early to execute");

_executeUpkeep(data);
autoExecutesMap.remove(id);
}

function _execute(
address to,
uint256 callValue,
bytes calldata data
) private returns (bytes memory) {
) private returns (bytes memory returnData) {
require(to != address(this), "SW: to cannot be this");

_requireNotBlaclisted(to, data);

if (data.length > 0) {
return to.functionCallWithValue(data, callValue);
returnData = to.functionCallWithValue(data, callValue);
} else {
Address.sendValue(payable(to), callValue);
}
Expand Down
10 changes: 10 additions & 0 deletions contracts/interfaces/IAutomationCompatible.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IAutomationCompatible {
function checkUpkeep(
bytes calldata
) external view returns (bool, bytes memory);

function performUpkeep(bytes calldata) external;
}
63 changes: 63 additions & 0 deletions contracts/interfaces/ISmartWallet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IAutomationCompatible.sol";

interface ISmartWallet is IAutomationCompatible {
struct AutoExecute {
bytes32 id;
address creator;
address callback;
bytes executeData;
address executeTo;
uint256 executeValue;
uint256 executeAfter;
}

function blacklist(address to, bytes4 funcSelector) external;

function removeFromBlacklist(address to, bytes4 funcSelector) external;

function blacklistBatch(
address[] calldata tos,
bytes4[] calldata funcSelectors
) external;

function removeFromBlacklistBatch(
address[] calldata tos,
bytes4[] calldata funcSelectors
) external;

function addToAutoExecute(
bytes32 id,
address callback,
bytes calldata executeData,
address executeTo,
uint256 executeValue,
uint256 executeAfter
) external;

function addToAllowlistWithPermit(
address addr,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;

function addToAllowlist(address addr) external;

function removeFromAllowlist(address addr) external;

function execute(
address to,
uint256 callValue,
bytes calldata data
) external returns (bytes memory returnData);

function executeBatch(
address[] calldata tos,
uint256[] calldata callValues,
bytes[] calldata datas
) external returns (bytes[] memory returnDatas);
}
30 changes: 30 additions & 0 deletions contracts/interfaces/ISmartWalletFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ISmartWalletFactory {
struct CreateWalletParams {
address owner;
address allowlistOperator;
address linkToken;
address clRegistrar;
address clRegistry;
address uniswapV3Router;
address wethToken;
bytes wethToLinkSwapPath;
}

function createWallet(
address owner,
address allowlistOperator
) external returns (address);

function create2Wallet(
address owner,
address allowlistOperator,
bytes32 salt
) external returns (address);

function predictCreate2Wallet(bytes32 salt) external view returns (address);

function validateWallet(address wallet) external view returns (bool);
}
Loading

0 comments on commit 9811ce0

Please sign in to comment.