contract InstaAccount is Record {

    event LogCast(address indexed origin, address indexed sender, uint value);

    receive() external payable {}

     /**
     * @dev Delegate the calls to Connector And this function is ran by cast().
     * @param _target Target to of Connector.
     * @param _data CallData of function in Connector.
    */
    function spell(address _target, bytes memory _data) internal {
        require(_target != address(0), "target-invalid");
        assembly {
            let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)

            switch iszero(succeeded)
                case 1 {
                    // throw if delegatecall failed
                    let size := returndatasize()
                    returndatacopy(0x00, 0x00, size)
                    revert(0x00, size)
                }
        }
    }

    /**
     * @dev This is the main function, Where all the different functions are called
     * from Smart Account.
     * @param _targets Array of Target(s) to of Connector.
     * @param _datas Array of Calldata(S) of function.
    */
    function cast(
        address[] calldata _targets,
        bytes[] calldata _datas,
        address _origin
    )
    external
    payable
    {
        require(isAuth(msg.sender) || msg.sender == instaIndex, "permission-denied");
        require(_targets.length == _datas.length , "array-length-invalid");
        IndexInterface indexContract = IndexInterface(instaIndex);
        bool isShield = shield;
        if (!isShield) {
            require(ConnectorsInterface(indexContract.connectors(version)).isConnector(_targets), "not-connector");
        } else {
            require(ConnectorsInterface(indexContract.connectors(version)).isStaticConnector(_targets), "not-static-connector");
        }
        for (uint i = 0; i < _targets.length; i++) {
            spell(_targets[i], _datas[i]);
        }
        address _check = indexContract.check(version);
        if (_check != address(0) && !isShield) require(CheckInterface(_check).isOk(), "not-ok");
        emit LogCast(_origin, msg.sender, msg.value);
    }

}
function cast(
    address[] calldata _targets,
    bytes[] calldata _datas,
    address _origin
)
external
payable
{
    require(isAuth(msg.sender) || msg.sender == instaIndex, "permission-denied");
    require(_targets.length == _datas.length , "array-length-invalid");
    IndexInterface indexContract = IndexInterface(instaIndex);
    bool isShield = shield;
    if (!isShield) {
        require(ConnectorsInterface(indexContract.connectors(version)).isConnector(_targets), "not-connector");
    } else {
        require(ConnectorsInterface(indexContract.connectors(version)).isStaticConnector(_targets), "not-static-connector");
    }
    for (uint i = 0; i < _targets.length; i++) {
        spell(_targets[i], _datas[i]);
    }
    address _check = indexContract.check(version);
    if (_check != address(0) && !isShield) require(CheckInterface(_check).isOk(), "not-ok");
    emit LogCast(_origin, msg.sender, msg.value);
}

/**
 * @dev This is the main function, Where all the different functions are called
 * from Smart Account.
 * @param _targets Array of Target(s) to of Connector.
 * @param _datas Array of Calldata(S) of function.
 */