{"functions": ["bridge_remove_operator", "bridge_set_outgoing_price", "bridge_set_operator", "bridge_incoming", "bridge_outgoing", "bridge_incoming_process"], "snippet": "\n# Elliptic Curve parameters for secp256k1\nP = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\nA = 0\nB = 7\nGx = 55066263022277343669578718895168534326250603453777594175500187360389116729240\nGy = 32670510020758816978083085130507043184471273380659243275938904335757337482424\nG = (Gx, Gy)\nN = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\nK = 10**18\n\ndef _inverse_mod(k, p):\n if k == 0:\n raise\n return pow(k, p - 2, p)\n\ndef _is_on_curve(point):\n if point is None:\n return True\n x, y = point\n return (y * y - (x * x * x + A * x + B)) % P == 0\n\ndef _point_add(point1, point2):\n if point1 is None:\n return point2\n if point2 is None:\n return point1\n x1, y1 = point1\n x2, y2 = point2\n if x1 == x2 and y1 != y2:\n return None\n if x1 == x2:\n m = (3 * x1 * x1 + A) * _inverse_mod(2 * y1, P)\n else:\n m = (y2 - y1) * _inverse_mod(x2 - x1, P)\n m %= P\n x3 = (m * m - x1 - x2) % P\n y3 = (m * (x1 - x3) - y1) % P\n return (x3, y3)\n\ndef _scalar_mult(k, point):\n result = None\n addend = point\n while k:\n if k & 1:\n result = _point_add(result, addend)\n addend = _point_add(addend, addend)\n k >>= 1\n return result\n\ndef _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n assert public_key_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n if not (1 <= r < N and 1 <= s < N):\n return False\n point = (int(public_key_hex[2:66], 16), int(public_key_hex[66:], 16))\n # print(type(msg_hash_hex), msg_hash_hex)\n e = int(msg_hash_hex[2:], 16)\n w = _inverse_mod(s, N)\n u1 = (e * w) % N\n u2 = (r * w) % N\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n return False\n x, y = q\n return r == x % N\n\ndef _ecdsa_recover(msg_hash_hex, signature_hex):\n assert msg_hash_hex.startswith('0x')\n assert signature_hex.startswith('0x')\n r = int(signature_hex[2:66], 16)\n s = int(signature_hex[66:130], 16)\n z = int(msg_hash_hex[2:], 16)\n\n if len(signature_hex[2:]) == 130:\n v = int(signature_hex[130:], 16)\n if v >= 27:\n recovery_id = v - 27\n else:\n recovery_id = v\n recovery_ids = [recovery_id]\n else:\n recovery_ids = [0, 1]\n\n for recovery_id in recovery_ids:\n for j in range(2):\n x = r + j * N\n if x >= P:\n continue\n\n y_squared = (pow(x, 3, P) + A * x + B) % P\n y = pow(y_squared, (P + 1) // 4, P)\n\n if y % 2 != recovery_id:\n y = P - y\n\n point = (x, y)\n if not _is_on_curve(point):\n continue\n\n r_inv = _inverse_mod(r, N)\n u1 = (-z * r_inv) % N\n u2 = (s * r_inv) % N\n\n q = _point_add(_scalar_mult(u1, G), _scalar_mult(u2, point))\n if q is None:\n continue\n\n public_key_hex = f\"0x{q[0]:064x}{q[1]:064x}\"\n if _ecdsa_verify(msg_hash_hex, signature_hex, public_key_hex):\n return public_key_hex\n\n return None\n\n\ndef _encode_uint256(value):\n return value.to_bytes(32, 'big')\n\ndef _encode_address(address_str):\n address_bytes = bytes.fromhex(address_str[2:])\n return b'\\x00' * (32 - len(address_bytes)) + address_bytes\n\ndef _encode_dynamic_bytes(data_hex):\n data_bytes = bytes.fromhex(data_hex)\n length = len(data_bytes)\n padded_length = (length + 31) // 32 * 32 # Calculate padded length for data\n return length.to_bytes(32, 'big') + data_bytes + b'\\x00' * (padded_length - length)\n\n# '{\"a\": [845300000000000000000000002, 8453, 43114, \"0x51055892893c17ae7db48a0c0f760145bfe9f1e5\", \"0x09ace2d19b0273a762b0fe22b9e5199505c778de\", 0, \"000000000000000000000000490537058bdddaae99dd4da8b5db5675936bfedf0000000000000000000000000000000000000000000000008ac7230489e80000\", \"0000000000000000000000000000000000000000000000000000000000000000\", \"034da1308a53b6586fed90af2bd4e48cc863913551cc41d6148f43441691e4fd1ea27a1e3daf2b4c1386d0426cc37a4423729204177740768970937c93d648961c\"], \"f\": \"bridge_incoming_process\", \"p\": \"zentest\"}'\ndef bridge_incoming_process(info, args):\n assert args['f'] == 'bridge_incoming_process'\n sender = info['sender']\n addr = handle_lookup(sender)\n print('bridge_incoming_process')\n\n txid = args['a'][0]\n source_chain_id = args['a'][1]\n dest_chain_id = args['a'][2]\n source_chain_sender = args['a'][3]\n dest_chain_recipient = args['a'][4]\n gas = args['a'][5]\n user_payload = args['a'][6]\n exsig = args['a'][7]\n signature = args['a'][8]\n\n encoded_txid = _encode_uint256(txid)\n encoded_source_chain_id = _encode_uint256(source_chain_id)\n encoded_dest_chain_id = _encode_uint256(dest_chain_id)\n encoded_source_chain_sender = _encode_address(source_chain_sender)\n encoded_dest_chain_recipient = _encode_address(dest_chain_recipient)\n offset_user_payload = 6 * 32\n encoded_offset_user_payload = _encode_uint256(offset_user_payload)\n\n header = b''.join([\n encoded_txid,\n encoded_source_chain_id,\n encoded_dest_chain_id,\n encoded_source_chain_sender,\n encoded_dest_chain_recipient,\n encoded_offset_user_payload,\n ])\n encoded_user_payload_data = _encode_dynamic_bytes(user_payload)\n\n encoded_data = b''.join([\n header,\n encoded_user_payload_data,\n ])\n print(f\"ABI Encoded Data (Pure Python): 0x{encoded_data.hex()}\")\n\n encoded_data_hash = keccak(encoded_data)\n x19_msg_prefix = b\"\\x19Ethereum Signed Message:\\n\" + str(len(encoded_data_hash)).encode('utf-8')\n x19_msg_hash = keccak(x19_msg_prefix + encoded_data_hash)\n print(f\"x19_msg (Pure Python): 0x{x19_msg_hash.hex()}\")\n\n print('x19', '0x'+x19_msg_hash.hex())\n print('signature', '0x'+signature)\n recovered_public_key = _ecdsa_recover('0x'+x19_msg_hash.hex(), '0x'+signature)\n print(f\"recovered public key: {recovered_public_key}\")\n if recovered_public_key:\n public_key_bytes = bytes.fromhex(recovered_public_key[2:])\n address_bytes = keccak(public_key_bytes)[-20:]\n address = '0x' + address_bytes.hex()\n print(f\"Recovered Ethereum address: {address}\")\n event('BridgeProcess', [address])\n\n\ndef bridge_incoming(info, args):\n assert args['f'] == 'bridge_incoming'\n print('bridge_incoming', args)\n\n tick = args['a'][0]\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase+string.digits+'_')\n\n operator, _ = get(tick, 'incoming_operator', None)\n assert operator is not None, \"Bridge is not initialized\"\n sender = info['sender']\n assert sender == operator, \"Only the operator can perform this operation\"\n\n amount = int(args['a'][1])\n assert amount > 0\n\n receiver = args['a'][2].lower()\n assert len(receiver) <= 42\n assert type(receiver) is str\n if len(receiver) == 42:\n assert receiver.startswith('0x')\n assert set(receiver[2:]) <= set(string.digits+'abcdef')\n else:\n assert len(receiver) > 4\n\n balance, _ = get(tick, 'balance', 0, receiver)\n balance = int(balance)\n balance += amount\n put(receiver, tick, 'balance', balance, receiver)\n\n asset_owner, _ = get('asset', 'owner', None, tick)\n total, _ = get(tick, 'total', 0)\n total = int(total)\n total += amount\n put(asset_owner, tick, 'total', total)\n\n # call('trade_market_order', ['USDC', None, 'ZENT', 50 * 10**18 // 1000])\n # sender_balance, _ = get(tick_1, 'balance', 0, addr)\n print('tick', tick, 'balance', balance)\n # print('quote_value > 0', quote_value)\n\n if tick != 'USDC':\n return\n\n base_tick = 'ZENT'\n quote_tick = tick\n pair = '%s_%s' % (base_tick, quote_tick)\n addr = receiver\n quote_sum = 0\n quote_balance = balance\n base_value = 10**18 // 1000 * 50 # 50 bytes\n trade_sell_start, _ = get('trade', f'{pair}_sell_start', 1)\n # trade_buy_start, _ = get('trade', f'{pair}_buy_start', 1)\n\n # break until the base balance is enough\n trade_sell_id = trade_sell_start\n while True:\n sell, _ = get('trade', f'{pair}_sell', None, str(trade_sell_id))\n if sell is None:\n break\n\n price = sell[3]\n print(-sell[1], quote_balance * K // price, base_value)\n dx_base = min(-sell[1], quote_balance * K // price, base_value)\n dx_quote = dx_base * price // K\n if dx_base == 0 or dx_quote == 0:\n break\n sell[1] += dx_base\n sell[2] -= dx_quote\n\n if quote_balance - dx_quote < 0:\n break\n quote_balance -= dx_quote\n quote_sum += dx_quote\n\n if sell[1] == 0 or sell[1] // price == 0:\n if sell[4]:\n prev_sell, _ = get('trade', f'{pair}_sell', None, str(sell[4]))\n prev_sell[5] = sell[5]\n put(prev_sell[0], 'trade', f'{pair}_sell', prev_sell, str(sell[4]))\n\n if sell[5]:\n next_sell, _ = get('trade', f'{pair}_sell', None, str(sell[5]))\n next_sell[4] = sell[4]\n put(next_sell[0], 'trade', f'{pair}_sell', next_sell, str(sell[5]))\n\n if sell[4] is not None and sell[5] is None:\n trade_sell_start = sell[4]\n put(addr, 'trade', f'{pair}_sell_start', trade_sell_start)\n elif sell[4] is None and sell[5] is None:\n trade_sell_new, _ = get('trade', f'{pair}_sell_new', 1)\n trade_sell_start = trade_sell_new\n put(addr, 'trade', f'{pair}_sell_start', trade_sell_start)\n\n print(f'{pair}_sell_to_refund', sell)\n if sell[1] < 0:\n balance, _ = get(base_tick, 'balance', 0, sell[0])\n balance -= sell[1]\n assert balance >= 0\n put(sell[0], base_tick, 'balance', balance, sell[0])\n\n put(sell[0], 'trade', f'{pair}_sell', None, str(trade_sell_id))\n else:\n put(sell[0], 'trade', f'{pair}_sell', sell, str(trade_sell_id))\n\n balance, _ = get(quote_tick, 'balance', 0, sell[0])\n balance += dx_quote\n assert balance >= 0\n put(addr, quote_tick, 'balance', balance, sell[0])\n\n base_value -= dx_base\n assert base_value >= 0\n balance, _ = get(base_tick, 'balance', 0, addr)\n balance += dx_base\n assert balance >= 0\n put(addr, base_tick, 'balance', balance, addr)\n\n if sell[4] is None:\n break\n trade_sell_id = sell[4]\n\n balance, _ = get(quote_tick, 'balance', 0, addr)\n balance -= quote_sum\n assert balance >= 0\n put(addr, quote_tick, 'balance', balance, addr)\n\n\ndef bridge_outgoing(info, args):\n assert args['f'] == 'bridge_outgoing'\n\n tick = args['a'][0]\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase+string.digits+'_')\n\n amount = int(args['a'][1])\n assert amount > 0\n\n chain = args['a'][2]\n assert chain in ['op-sepolia']\n\n sender = info['sender']\n\n\ndef bridge_set_operator(info, args):\n assert args['f'] == 'bridge_set_operator'\n print('bridge_set_operator', args)\n\n tick = args['a'][0]\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase+string.digits+'_')\n\n asset_owner, _ = get('asset', 'owner', None, tick)\n sender = info['sender']\n addr = handle_lookup(sender)\n print('bridge_set_operator', asset_owner, addr)\n assert addr == asset_owner, \"Only the asset owner can perform this operation\"\n\n operator = args['a'][1].lower()\n assert type(operator) is str\n assert len(operator) == 42\n assert operator.startswith('0x')\n assert set(operator[2:]) <= set(string.digits+'abcdef')\n\n put(addr, tick, 'incoming_operator', operator)\n\n\ndef bridge_remove_operator(info, args):\n assert args['f'] == 'bridge_remove_operator'\n print('bridge_remove_operator', args)\n\n tick = args['a'][0]\n assert type(tick) is str\n assert len(tick) > 0 and len(tick) < 42\n assert tick[0] in string.ascii_uppercase\n assert set(tick) <= set(string.ascii_uppercase+string.digits+'_')\n\n asset_owner, _ = get('asset', 'owner', None, tick)\n sender = info['sender']\n addr = handle_lookup(sender)\n # print('bridge_remove_operator', asset_owner, addr)\n assert addr == asset_owner, \"Only the asset owner can perform this operation\"\n\n # operator = args['a'][1].lower()\n # assert type(operator) is str\n # assert len(operator) == 42\n # assert operator.startswith('0x')\n # assert set(operator[2:]) <= set(string.digits+'abcdef')\n\n put(addr, tick, 'incoming_operator', None)\n\ndef bridge_set_outgoing_price(info, args):\n assert args['f'] == 'bridge_set_outgoing_price'\n print('bridge_set_outgoing_price', args)\n"}