Merge pull request #235 from Instadapp/spell-connector

DSA-Spell connector
This commit is contained in:
0xPradyuman 2022-06-21 22:26:15 +05:30 committed by GitHub
commit 1e78276bb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 1857 additions and 6 deletions

View File

@ -26,6 +26,15 @@ interface AccountInterface {
function enable(address) external;
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface, InstaMapping } from "./interfaces.sol";
import { MemoryInterface, InstaMapping, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
@ -21,6 +21,16 @@ abstract contract Stores {
*/
MemoryInterface constant internal instaMemory = MemoryInterface(0xc109f7Ef06152c3a63dc7254fD861E612d3Ac571);
/**
* @dev Return InstaList address
*/
ListInterface internal constant instaList = ListInterface(0x3565F6057b7fFE36984779A507fC87b31EFb0f09);
/**
* @dev Return connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x67fCE99Dd6d8d659eea2a1ac1b8881c57eb6592B);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpellArbitrum is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -21,6 +21,15 @@ interface AccountInterface {
function enable(address) external;
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface } from "./interfaces.sol";
import { MemoryInterface, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
@ -21,6 +21,16 @@ abstract contract Stores {
*/
MemoryInterface constant internal instaMemory = MemoryInterface(0x3254Ce8f5b1c82431B8f21Df01918342215825C2);
/**
* @dev Return InstaList address
*/
ListInterface internal constant instaList = ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687);
/**
* @dev Return connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpellAvalanche is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -34,6 +34,16 @@ interface AccountInterface {
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface } from "./interfaces.sol";
import { MemoryInterface, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
/**
@ -22,6 +22,16 @@ abstract contract Stores {
MemoryInterface internal constant instaMemory =
MemoryInterface(0x56439117379A53bE3CC2C55217251e2481B7a1C8);
/**
* @dev Return InstaList address
*/
ListInterface internal constant instaList = ListInterface(0x10e166c3FAF887D8a61dE6c25039231eE694E926);
/**
* @dev Return connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x819910794a030403F69247E1e5C0bBfF1593B968);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpellFantom is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -27,6 +27,15 @@ interface AccountInterface {
function enable(address) external;
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface, InstaMapping } from "./interfaces.sol";
import { MemoryInterface, InstaMapping, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
@ -26,6 +26,16 @@ abstract contract Stores {
*/
InstaMapping constant internal instaMapping = InstaMapping(0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88);
/**
* @dev Return InstaList Address
*/
ListInterface internal constant instaList = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb);
/**
* @dev Return connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpell is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -23,6 +23,15 @@ interface AccountInterface {
function enable(address) external;
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface } from "./interfaces.sol";
import { MemoryInterface, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
@ -20,6 +20,16 @@ abstract contract Stores {
*/
MemoryInterface constant internal instaMemory = MemoryInterface(0x3254Ce8f5b1c82431B8f21Df01918342215825C2);
/**
* @dev Return InstaList address
*/
ListInterface internal constant instaList = ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687);
/**
* @dev Returns connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpellOptimism is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -26,6 +26,15 @@ interface AccountInterface {
function enable(address) external;
function disable(address) external;
function isAuth(address) external view returns (bool);
function cast(
string[] calldata _targetNames,
bytes[] calldata _datas,
address _origin
) external payable returns (bytes32[] memory responses);
}
interface ListInterface {
function accountID(address) external returns (uint64);
}
interface InstaConnectors {

View File

@ -1,7 +1,7 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import { MemoryInterface, InstaMapping } from "./interfaces.sol";
import { MemoryInterface, InstaMapping, ListInterface, InstaConnectors } from "./interfaces.sol";
abstract contract Stores {
@ -21,6 +21,16 @@ abstract contract Stores {
*/
MemoryInterface constant internal instaMemory = MemoryInterface(0x6C7256cf7C003dD85683339F75DdE9971f98f2FD);
/**
* @dev Return InstaList address
*/
ListInterface internal constant instaList = ListInterface(0x839c2D3aDe63DF5b0b8F3E57D5e145057Ab41556);
/**
* @dev Return connectors registry address
*/
InstaConnectors internal constant instaConnectors = InstaConnectors(0x2A00684bFAb9717C21271E0751BCcb7d2D763c88);
/**
* @dev Get Uint value from InstaMemory Contract.
*/

View File

@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
contract Events {
event LogCastOnDSA(
address indexed targetDSA,
string[] connectors,
bytes[] datas
);
event LogCastAny(
string[] connectors,
string connectorName,
string eventName,
bytes eventParam
);
}

View File

@ -0,0 +1,91 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title DSA Spell.
* @dev Cast spells on DSA.
*/
import { AccountInterface } from "../../common/interfaces.sol";
import { Stores } from "../../common/stores.sol";
import { Events } from "./events.sol";
abstract contract DSASpellsResolver is Events, Stores {
/**
*@dev Casts spells on a DSA, caller DSA should be an auth of the target DSA. Reverts if any spell failed.
*@notice Interact with a target DSA by casting spells on it.
*@param targetDSA target DSA to cast spells on.
*@param connectors Array of connector names (For example, ["1INCH-A", "BASIC-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castOnDSA(
address targetDSA,
string[] memory connectors,
bytes[] memory datas
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
require(instaList.accountID(targetDSA) != 0, "not-a-DSA");
AccountInterface(targetDSA).cast(connectors, datas, address(this));
_eventName = "LogCastOnDSA(address,string[],bytes[])";
_eventParam = abi.encode(targetDSA, connectors, datas);
}
/**
*@dev Casts spell on caller DSA. Stops casting further spells as soon as a spell gets casted successfully.
* Reverts if none of the spells is successful.
*@notice Casts the first successful spell on the DSA.
*@param connectors Array of connector names, in preference order, if any (For example, ["1INCH-A", "ZEROX-A"]).
*@param datas Array of connector calldatas (function selectors encoded with parameters).
*/
function castAny(string[] memory connectors, bytes[] memory datas)
external
payable
returns (string memory eventName, bytes memory eventParam)
{
uint256 _length = connectors.length;
require(_length > 0, "zero-length-not-allowed");
require(datas.length == _length, "calldata-length-invalid");
(bool isOk, address[] memory _connectors) = instaConnectors
.isConnectors(connectors);
require(isOk, "connector-names-invalid");
string memory _connectorName;
string memory _eventName;
bytes memory _eventParam;
bytes memory returnData;
bool success;
for (uint256 i = 0; i < _length; i++) {
(success, returnData) = _connectors[i].delegatecall(datas[i]);
if (success) {
_connectorName = connectors[i];
(_eventName, _eventParam) = abi.decode(
returnData,
(string, bytes)
);
break;
}
}
require(success, "dsa-spells-failed");
eventName = "LogCastAny(string[],string,string,bytes)";
eventParam = abi.encode(
connectors,
_connectorName,
_eventName,
_eventParam
);
}
}
contract ConnectV2DSASpellPolygon is DSASpellsResolver {
string public name = "DSA-Spell-v1.0";
}

View File

@ -0,0 +1,180 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellArbitrum__factory } from "../../../typechain";
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellArbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
});
it("Deposit eth into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit eth into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aETH = "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8";
let aEth = new ethers.Contract(aETH, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[ETH, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[ETH, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A"];
let methods = ["deposit"];
let params = [
[ETH, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aEth.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,185 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellAvalanche__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let walletBsigner: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
});
it("Deposit avax into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit avax into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let AVAX = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aAVAX = "0x6d80113e533a2C0fe82EaBD35f1875DcEA89Ea97";
let aAvax = new ethers.Contract(aAVAX, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[AVAX, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[AVAX, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A", "AAVE-V2-A"];
let methods = ["deposit","deposit"];
let params = [
[AVAX, ethers.utils.parseEther("10"), 0, 0],
[AVAX, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aAvax.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,182 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/fantom/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellFantom__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import BigNumber from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellFantom__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
});
it("Deposit ftm into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit ftm into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let FTM = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let aFTM = "0x6d80113e533a2C0fe82EaBD35f1875DcEA89Ea97";
let USDC = "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aFtm = new ethers.Contract(aFTM, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[FTM, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[FTM, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 5), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e5).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A"];
let methods = ["deposit"];
let params = [
[FTM, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aFtm.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,176 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpell__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import BigNumber from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpell__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
});
it("Deposit eth into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit eth into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aETH = "0x030bA81f1c18d280636F32af80b9AAd02Cf0854e";
let aEth = new ethers.Contract(aETH, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A"];
let methods = ["withdraw"];
let params = [
[ETH, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(new BigNumber(8).multipliedBy(1e18).toString());
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V2-A", "AAVE-V1-A"];
let methods = ["deposit", "deposit"];
let params = [
[ETH, ethers.utils.parseEther("10"), 0, 0],
[ETH, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aEth.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,180 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/optimism/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellOptimism__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import BigNumber from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellOptimism__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
});
it("Deposit eth into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit eth into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0x7F5c764cBc14f9669B88837ca1490cCa17c31607";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aETH = "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8";
let aEth = new ethers.Contract(aETH, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[ETH, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[ETH, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A"];
let methods = ["deposit"];
let params = [
[ETH, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aEth.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,185 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { addresses } from "../../../scripts/tests/polygon/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellPolygon__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let walletBsigner: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellPolygon__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector address", connector.address);
});
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
});
it("Deposit matic into DSA wallet 0", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("Deposit matic into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let MATIC = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
let aMATIC = "0x6d80113e533a2C0fe82EaBD35f1875DcEA89Ea97";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aMatic = new ethers.Contract(aMATIC, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[MATIC, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[MATIC, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A", "AAVE-V2-A"];
let methods = ["deposit","deposit"];
let params = [
[MATIC, ethers.utils.parseEther("10"), 0, 0],
[MATIC, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aMatic.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});