// SPDX-License-Identifier: MIT pragma solidity 0.7.6; pragma abicoder v2; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import "./interfaces/IInstanceRegistry.sol"; import "./interfaces/IInstanceFactory.sol"; struct InstanceAdditionData { address tokenAddress; uint40 smallDenomination; uint16 base10Exponent; uint24 uniPoolSwappingFee; uint16 protocolFee; } contract InstanceAdditionDataProvider { InstanceAdditionData[] public toAddData; constructor(InstanceAdditionData[] memory _toAdd) { for (uint256 i = 0; i < _toAdd.length; i++) { toAddData.push(_toAdd[i]); } } function getAllDataToAdd() external view returns (InstanceAdditionData[] memory) { return toAddData; } } contract InstanceAdditionProposal { using SafeMath for uint256; InstanceAdditionDataProvider public immutable provider; IInstanceFactory public immutable instanceFactory; IInstanceRegistry public immutable instanceRegistry; event AddInstanceForRegistry(address instance, address token, uint256 denomination); constructor(address _instanceFactory, address _instanceRegistry, InstanceAdditionData[] memory _toAdd) { provider = new InstanceAdditionDataProvider(_toAdd); instanceFactory = IInstanceFactory(_instanceFactory); instanceRegistry = IInstanceRegistry(_instanceRegistry); } function executeProposal() external { InstanceAdditionData[] memory _toAddData = provider.getAllDataToAdd(); uint256 howMany = _toAddData.length; for (uint256 i = 0; i < howMany; i++) { // Read out the data for the new instance InstanceAdditionData memory data = _toAddData[i]; // Safely calculate the denomination uint256 denomination = uint256(data.smallDenomination).mul(10 ** uint256(data.base10Exponent)); // Create the instance address instance = instanceFactory.createInstanceClone(denomination, data.tokenAddress); // Prepare the data for the registry. IInstanceRegistry.Instance memory newInstanceData = IInstanceRegistry.Instance( data.tokenAddress != address(0), IERC20(data.tokenAddress), IInstanceRegistry.InstanceState.ENABLED, data.uniPoolSwappingFee, data.protocolFee ); // Convert the data. IInstanceRegistry.Tornado memory tornadoForUpdate = IInstanceRegistry.Tornado(instance, newInstanceData); // Update the instance data in the registry. instanceRegistry.updateInstance(tornadoForUpdate); emit AddInstanceForRegistry(address(instance), data.tokenAddress, denomination); } } function getDataToAddByIndex(uint256 index) external view returns (InstanceAdditionData memory data) { // The compiler is behaving weird here. Something to do with struct type inference. return (provider.getAllDataToAdd())[index]; } function getAllDataToAdd() external view returns (InstanceAdditionData[] memory) { return provider.getAllDataToAdd(); } }