diff --git a/contracts/arbitrum/common/stores.sol b/contracts/arbitrum/common/stores.sol index dce4a455..40dd2731 100644 --- a/contracts/arbitrum/common/stores.sol +++ b/contracts/arbitrum/common/stores.sol @@ -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 InstaConnectors Registry Address + */ + InstaConnectors internal constant instaConnectors = InstaConnectors(0x67fCE99Dd6d8d659eea2a1ac1b8881c57eb6592B); + /** * @dev Get Uint value from InstaMemory Contract. */ diff --git a/contracts/arbitrum/connectors/spell/events.sol b/contracts/arbitrum/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/arbitrum/connectors/spell/events.sol +++ b/contracts/arbitrum/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/arbitrum/connectors/spell/helpers.sol b/contracts/arbitrum/connectors/spell/helpers.sol deleted file mode 100644 index 5f8d3d9a..00000000 --- a/contracts/arbitrum/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x3565F6057b7fFE36984779A507fC87b31EFb0f09); -} diff --git a/contracts/arbitrum/connectors/spell/main.sol b/contracts/arbitrum/connectors/spell/main.sol index 5e0356d4..47d65d38 100644 --- a/contracts/arbitrum/connectors/spell/main.sol +++ b/contracts/arbitrum/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpellArbitrum is DSASpell { + string public name = "DSA-Spell-v1.0"; } diff --git a/contracts/avalanche/common/stores.sol b/contracts/avalanche/common/stores.sol index 97f51614..3d35be30 100644 --- a/contracts/avalanche/common/stores.sol +++ b/contracts/avalanche/common/stores.sol @@ -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 InstaConnectors Registry address + */ + InstaConnectors internal constant instaConnectors = InstaConnectors(0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14); + /** * @dev Get Uint value from InstaMemory Contract. */ diff --git a/contracts/avalanche/connectors/spell/events.sol b/contracts/avalanche/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/avalanche/connectors/spell/events.sol +++ b/contracts/avalanche/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/avalanche/connectors/spell/helpers.sol b/contracts/avalanche/connectors/spell/helpers.sol deleted file mode 100644 index 0576e10e..00000000 --- a/contracts/avalanche/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687); -} diff --git a/contracts/avalanche/connectors/spell/main.sol b/contracts/avalanche/connectors/spell/main.sol index 5e0356d4..d203022e 100644 --- a/contracts/avalanche/connectors/spell/main.sol +++ b/contracts/avalanche/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpellAvalanche is DSASpell { + string public name = "DSA-Spell-v1.0"; } diff --git a/contracts/fantom/common/stores.sol b/contracts/fantom/common/stores.sol index 0e16eb06..72285b6d 100644 --- a/contracts/fantom/common/stores.sol +++ b/contracts/fantom/common/stores.sol @@ -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. */ diff --git a/contracts/fantom/connectors/spell/events.sol b/contracts/fantom/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/fantom/connectors/spell/events.sol +++ b/contracts/fantom/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/fantom/connectors/spell/helpers.sol b/contracts/fantom/connectors/spell/helpers.sol deleted file mode 100644 index ae065b8b..00000000 --- a/contracts/fantom/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x10e166c3FAF887D8a61dE6c25039231eE694E926); -} diff --git a/contracts/fantom/connectors/spell/main.sol b/contracts/fantom/connectors/spell/main.sol index 5e0356d4..15bce48d 100644 --- a/contracts/fantom/connectors/spell/main.sol +++ b/contracts/fantom/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpellFantom is DSASpell { + string public name = "DSA-Spell-v1.0"; } diff --git a/contracts/mainnet/common/stores.sol b/contracts/mainnet/common/stores.sol index 25cb226f..8be01eb7 100644 --- a/contracts/mainnet/common/stores.sol +++ b/contracts/mainnet/common/stores.sol @@ -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. */ diff --git a/contracts/mainnet/connectors/spell/events.sol b/contracts/mainnet/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/mainnet/connectors/spell/events.sol +++ b/contracts/mainnet/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/mainnet/connectors/spell/helpers.sol b/contracts/mainnet/connectors/spell/helpers.sol deleted file mode 100644 index a0a7582a..00000000 --- a/contracts/mainnet/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); -} diff --git a/contracts/mainnet/connectors/spell/main.sol b/contracts/mainnet/connectors/spell/main.sol index 5e0356d4..d2ca441e 100644 --- a/contracts/mainnet/connectors/spell/main.sol +++ b/contracts/mainnet/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpell is DSASpell { + string public name = "DSA-Spell-v1.0"; } diff --git a/contracts/optimism/common/stores.sol b/contracts/optimism/common/stores.sol index 09d3cfca..d13351bb 100644 --- a/contracts/optimism/common/stores.sol +++ b/contracts/optimism/common/stores.sol @@ -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. */ diff --git a/contracts/optimism/connectors/spell/events.sol b/contracts/optimism/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/optimism/connectors/spell/events.sol +++ b/contracts/optimism/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/optimism/connectors/spell/helpers.sol b/contracts/optimism/connectors/spell/helpers.sol deleted file mode 100644 index 0576e10e..00000000 --- a/contracts/optimism/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687); -} diff --git a/contracts/optimism/connectors/spell/main.sol b/contracts/optimism/connectors/spell/main.sol index 5e0356d4..821c6b0b 100644 --- a/contracts/optimism/connectors/spell/main.sol +++ b/contracts/optimism/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpellOptimism is DSASpell { + string public name = "DSA-Spell-v1.0"; } diff --git a/contracts/polygon/common/stores.sol b/contracts/polygon/common/stores.sol index e5e21f55..9231dcde 100644 --- a/contracts/polygon/common/stores.sol +++ b/contracts/polygon/common/stores.sol @@ -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. */ diff --git a/contracts/polygon/connectors/spell/events.sol b/contracts/polygon/connectors/spell/events.sol index 1fff84f3..75048eff 100644 --- a/contracts/polygon/connectors/spell/events.sol +++ b/contracts/polygon/connectors/spell/events.sol @@ -4,8 +4,9 @@ pragma abicoder v2; contract Events { event LogCastDSA( - address indexed targetDSA, + address indexed targetDSA, string[] connectors, bytes[] datas ); + event LogCastSpells(string[] eventNames, bytes[] eventParams); } diff --git a/contracts/polygon/connectors/spell/helpers.sol b/contracts/polygon/connectors/spell/helpers.sol deleted file mode 100644 index ae03c240..00000000 --- a/contracts/polygon/connectors/spell/helpers.sol +++ /dev/null @@ -1,12 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import { ListInterface } from "../../common/interfaces.sol"; - -contract SpellHelpers { - /** - * @dev InstaList - */ - ListInterface internal constant instaList = - ListInterface(0x839c2D3aDe63DF5b0b8F3E57D5e145057Ab41556); -} diff --git a/contracts/polygon/connectors/spell/main.sol b/contracts/polygon/connectors/spell/main.sol index 5e0356d4..0252cc63 100644 --- a/contracts/polygon/connectors/spell/main.sol +++ b/contracts/polygon/connectors/spell/main.sol @@ -3,21 +3,21 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** - * @title Spell. - * @dev Cast on DSAs. + * @title DSA Spell. + * @dev Cast spells on DSA. */ // import files import { AccountInterface } from "../../common/interfaces.sol"; -import { SpellHelpers } from "./helpers.sol"; +import { Stores } from "../../common/stores.sol"; import { Events } from "./events.sol"; -abstract contract Spell is SpellHelpers, Events { +abstract contract DSASpell is Events, Stores { /** *@dev Cast spells on DSA. *@param targetDSA target DSA to cast spells on. - *@param connectors connector names. - *@param datas datas for the cast. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. */ function castDSA( address targetDSA, @@ -30,13 +30,48 @@ abstract contract Spell is SpellHelpers, Events { { require(instaList.accountID(targetDSA) != 0, "not-a-DSA"); - AccountInterface(targetDSA).cast(connectors, datas, address(0)); + AccountInterface(targetDSA).cast(connectors, datas, address(this)); _eventName = "LogCastDSA(address,string[],bytes[])"; _eventParam = abi.encode(targetDSA, connectors, datas); } + + /** + *@dev Perform spells. + *@param connectors Array of connector names. + *@param datas Array of connector calldatas. + */ + function castSpells(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 _eventNames = new string[](_length); + bytes[] memory _eventParams = new bytes[](_length); + + for (uint256 i = 0; i < _length; i++) { + (bool success, bytes memory returnData) = _connectors[i] + .delegatecall(datas[i]); + require(success, "spells-failed"); + (_eventNames[i], _eventParams[i]) = abi.decode( + returnData, + (string, bytes) + ); + } + + eventName = "LogCastSpells(string[],bytes[])"; + eventParam = abi.encode(_eventNames, _eventParams); + } } -contract ConnectV2SpellConnectorPolygon is Spell { - string public name = "Spell-Connector-v1.0"; +contract ConnectV2DSASpellPolygon is DSASpell { + string public name = "DSA-Spell-v1.0"; }