diff --git a/target_chains/ethereum/sdk/solidity/CombinePythPrice.sol b/target_chains/ethereum/sdk/solidity/CombinePythPrice.sol
new file mode 100644
index 0000000000..ba000f7e76
--- /dev/null
+++ b/target_chains/ethereum/sdk/solidity/CombinePythPrice.sol
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+import {PythStructs} from "./PythStructs.sol";
+
+/**
+ * @title PythPriceCombinationLibrary
+ * @dev A library for combining Pyth prices using mathematical operations.
+ */
+
+library CombinePythPrice {
+    /////////////////////
+    //     Errors      //
+    /////////////////////
+
+    error DivisionByZero();
+    error ExceedingComputationalRange();
+    error AddingPricesOfDifferentExponents(int32 expo1, int32 expo2);
+    error MathErrorWhileScaling();
+
+    // Constants for working with Pyth's number representation
+    uint64 private constant MAX_PD_V_U64 = (1 << 28) - 1;
+    uint64 private constant PD_SCALE = 1_000_000_000;
+    int32 private constant PD_EXPO = -9;
+
+    /**
+     *
+     * @param p1 Price 1
+     * @param p2 Price 2
+     * @return result of the addition of the prices
+     * @dev Function to add two pyth price when the exponents are same.
+     */
+    function addPrices(
+        PythStructs.Price memory p1,
+        PythStructs.Price memory p2
+    ) internal pure returns (PythStructs.Price memory result) {
+        int64 _price;
+        uint64 _conf;
+
+        if (p1.expo != p2.expo) {
+            revert AddingPricesOfDifferentExponents(p1.expo, p2.expo);
+        } else {
+            _price = p1.price + p2.price;
+            _conf = p1.conf + p2.conf;
+
+            return
+                PythStructs.Price({
+                    price: _price,
+                    conf: _conf,
+                    expo: p1.expo,
+                    publishTime: min(p1.publishTime, p2.publishTime)
+                });
+        }
+    }
+
+    /**
+     *
+     * @param p1 Price 1
+     * @param p2 Price 2
+     * @param expo Exponent value to which the price should be transformed to.
+     * @return result of the addition of the prices
+     * @dev Function to convert the price and confindence interval to the required exponent and then add the two pyth prices.
+     */
+    function addPriceToScaled(
+        PythStructs.Price memory p1,
+        PythStructs.Price memory p2,
+        int32 expo
+    ) internal pure returns (PythStructs.Price memory result) {
+        PythStructs.Price memory _p1 = p1.expo != expo
+            ? scaleToExponent(p1, expo)
+            : p1;
+        PythStructs.Price memory _p2 = p2.expo != expo
+            ? scaleToExponent(p2, expo)
+            : p2;
+
+        return addPrices(_p1, _p2);
+    }
+
+    /**
+     *
+     * @param self Price 1
+     * @param other Price 2
+     * @return result of the addition of the prices
+     * @dev Convert the price and confidence interval of Price 2 to the exponent of Price 1 and adds the two prices.
+     */
+    function convertAndAddPrices(
+        PythStructs.Price memory self,
+        PythStructs.Price memory other
+    ) internal pure returns (PythStructs.Price memory result) {
+        if (self.expo != other.expo) {
+            PythStructs.Price memory scaledP2 = scaleToExponent(
+                other,
+                self.expo
+            );
+            return addPrices(self, scaledP2);
+        } else {
+            return addPrices(self, other);
+        }
+    }
+
+    /**
+     *
+     * @param self Price
+     * @param quote Price
+     * @param targetExpo Exponent of the result.
+     * @return result Returns the current price in a different quote currency.
+     * @dev  Get the current price of this account in a different quote currency.
+     * If this account represents the price of the product X/Z, and `quote` represents the price  of the product Y/Z, this method returns the price of X/Y. Use this method to get the price of e.g., mSOL/SOL from the mSOL/USD and SOL/USD accounts
+     */
+    function getPriceInQuote(
+        PythStructs.Price memory self,
+        PythStructs.Price memory quote,
+        int32 targetExpo
+    ) public pure returns (PythStructs.Price memory result) {
+        PythStructs.Price memory divPrice = div(self, quote);
+
+        if (divPrice.price != 0) {
+            return scaleToExponent(divPrice, targetExpo);
+        }
+    }
+
+    /**
+     * @param self The price to be divided
+     * @param other The price to divide by
+     * @return result The resulting price after division
+     * @dev Divide `se;f` price by `other` while propagating the uncertainty in both prices into the result.
+     * This method will automatically select a reasonable exponent for the result. If both `self` and `other` are normalized, the
+     * exponent is `self.expo + PD_EXPO - other.expo` (i.e., the fraction has `PD_EXPO` digits of additional precision). If they are not
+     * normalized, this method will normalize them, resulting in an unpredictable result exponent. If the result is used in a context
+     * that requires a specific exponent, please call `scale_to_exponent` on it.
+     */
+    function div(
+        PythStructs.Price memory self,
+        PythStructs.Price memory other
+    ) public pure returns (PythStructs.Price memory result) {
+        //Return zero price struct on denominator being 0
+        if (other.price == 0) {
+            revert DivisionByZero();
+        }
+
+        /// Price is not guaranteed to store its price/confidence in normalized form.
+        /// Normalize them here to bound the range of price/conf, which is required to perform arithmetic operations.
+        PythStructs.Price memory base = normalize(self);
+        PythStructs.Price memory _other = normalize(other);
+
+        //Converting to unsigned.
+        (uint64 basePrice, int64 baseSign) = toUnsigned(base.price);
+        (uint64 _otherPrice, int64 _otherSign) = toUnsigned(_other.price);
+
+        // Compute the midprice, base in terms of other.
+        uint64 midPrice = ((basePrice * PD_SCALE) / _otherPrice);
+        int32 midPriceExpo = ((base.expo - _other.expo) + PD_EXPO);
+
+        /// Compute the confidence interval.
+        ///
+        /// This code uses the 1-norm instead of the 2-norm for computational reasons.
+        /// Let p +- a and q +- b be the two arguments to this method.
+        /// The correct formula is p/q * sqrt( (a/p)^2 + (b/q)^2 ).
+        /// This quantity is difficult to compute due to the sqrt and overflow/underflow considerations.
+        ///
+        /// This code instead computes p/q * (a/p + b/q) = a/q + pb/q^2 .
+        /// This quantity is at most a factor of sqrt(2) greater than the correct result, which shouldn't matter considering that confidence intervals are typically ~0.1% of the price.
+
+        /// This uses 57 bits and has an exponent of PD_EXPO.
+        uint64 otherConfPct = ((_other.conf * PD_SCALE) / _otherPrice);
+
+        /// first term is 57 bits, second term is 57 + 58 - 29 = 86 bits. Same exponent as the midprice.
+        uint128 conf = uint128((base.conf * PD_SCALE) / _otherPrice) +
+            (uint128(otherConfPct) * uint128(midPrice)) /
+            uint128(PD_SCALE);
+
+        if (conf < type(uint64).max) {
+            return
+                PythStructs.Price({
+                    price: int64(midPrice) * baseSign * _otherSign,
+                    conf: uint64(conf),
+                    expo: midPriceExpo,
+                    publishTime: min(self.publishTime, _other.publishTime)
+                });
+        } else {
+            revert ExceedingComputationalRange();
+        }
+    }
+
+    /**
+     *
+     * @param a Unixtimestamp A
+     * @param b Unixtimestamp B
+     * @dev Helper function to find the minimum of two Unix timestamps
+     */
+    function min(uint256 a, uint256 b) internal pure returns (uint256) {
+        return a < b ? a : b;
+    }
+
+    /**
+     *
+     * @param price Input the price value that needs to be Normalized
+     * @dev Return the price struct after normalizing the price and confidence interval between the values of MAX_PD_V_I64 and MIN_PD_V_I64.
+     * MAX_PD_V_I64 = int64(MAX_PD_V_U64) i.e int64((1 << 28) - 1)
+     * MIN_PD_V_I64 = -MAX_PD_V_I64
+     */
+    function normalize(
+        PythStructs.Price memory price
+    ) internal pure returns (PythStructs.Price memory result) {
+        (uint64 p, int64 _s) = toUnsigned(price.price);
+        uint64 c = price.conf;
+        int32 e = price.expo;
+
+        ///Revert transaction incase `p` or `c` is zero leading to division by zero error.
+        if (p == 0 || c == 0) {
+            revert DivisionByZero();
+        }
+
+        // Scaling down if `p` and `c` are above MAX_PD_U64
+        while (p > MAX_PD_V_U64 || c > MAX_PD_V_U64) {
+            p /= 10;
+            c /= 10;
+            e += 1;
+            ///Returns 0 incase of `p` or `c` becomes 0 during normalization.
+            if (p == 0 || c == 0) {
+                revert DivisionByZero();
+            }
+        }
+
+        int64 signedPrice = int64(p) * _s;
+        return
+            PythStructs.Price({
+                price: signedPrice,
+                conf: c,
+                expo: e,
+                publishTime: price.publishTime
+            });
+    }
+
+    /**
+     *
+     * @param x Price value that needs to convert to be unsigned integer
+     * @return abs value of x
+     * @return sign of x
+     * @dev returns the unsigned value and the sign of the signed integer provided in the argument.
+     */
+    function toUnsigned(int64 x) internal pure returns (uint64, int64) {
+        if (x == type(int64).min) {
+            //Edge case
+            return (uint64(type(int64).max) + 1, -1);
+        } else if (x < 0) {
+            return (uint64(-x), -1);
+        } else {
+            return (uint64(x), 1);
+        }
+    }
+
+    /**
+     *
+     * @param self The price struct that needs to be scaled to the required exponent
+     * @param targetExpo The target exponent that the price needs to be scaled to
+     * @dev returns the price after scaling the it to the target exponent.
+     */
+    function scaleToExponent(
+        PythStructs.Price memory self,
+        int32 targetExpo
+    ) internal pure returns (PythStructs.Price memory result) {
+        int256 delta = targetExpo - self.expo;
+        int64 p = self.price;
+        uint64 c = self.conf;
+
+        if (delta >= 0) {
+            while (delta > 0 && (p != 0 || c != 0)) {
+                p = p / 10;
+                c = c / 10;
+                delta--;
+            }
+        } else {
+            while (delta < 0) {
+                /// Following checks for p:
+                ///1. Overflow
+                ///2. Underflow
+                ///3. Division by 0
+                ///4. min of int64 when multiplied by 10 causes underflow
+                if (
+                    p > type(int64).max / 10 ||
+                    p < type(int64).min / 10 ||
+                    (p == type(int64).min && p % 10 != 0)
+                ) {
+                    revert MathErrorWhileScaling();
+                }
+
+                /// Following checks for c:
+                ///1. Overflow
+                ///2. Division by 0
+                if (c > type(uint64).max / 10 || c % 10 != 0) {
+                    revert MathErrorWhileScaling();
+                }
+
+                p = p * 10;
+                c = c * 10;
+                delta++;
+            }
+        }
+
+        return PythStructs.Price(p, c, targetExpo, self.publishTime);
+    }
+}
diff --git a/target_chains/ethereum/sdk/solidity/Test/CombinePythPrice.t.sol b/target_chains/ethereum/sdk/solidity/Test/CombinePythPrice.t.sol
new file mode 100644
index 0000000000..ab8580a089
--- /dev/null
+++ b/target_chains/ethereum/sdk/solidity/Test/CombinePythPrice.t.sol
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: SEE LICENSE IN LICENSE
+pragma solidity ^0.8.25;
+
+import {Test, console2} from "forge-std/Test.sol";
+import {CombinePythPrice} from "src/CombinePythPrice.sol";
+import {PythStructs} from "src/PythStructs.sol";
+
+contract CombinePythPriceTest is Test {
+    PythStructs.Price public Price;
+    uint64 private constant PD_SCALE = 1_000_000_000;
+
+    function setUp() public view {}
+
+    ////////////////////////////////
+    //      toUnsigned()          //
+    ////////////////////////////////
+
+    function testToUnsignedPositive() public pure {
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(100);
+        assertEq(value, 100);
+        assertEq(sign, 1);
+    }
+
+    function testToUnsignedNegative() public pure {
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(-100);
+        assertEq(value, 100);
+        assertEq(sign, -1);
+    }
+
+    function testToUnsignedZero() public pure {
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(0);
+        assertEq(value, 0);
+        assertEq(sign, 1);
+    }
+
+    function testToUnsignedMinInt64() public pure {
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(
+            type(int64).min
+        );
+        assertEq(value, uint64(type(int64).max) + 1);
+        assertEq(sign, -1);
+    }
+
+    function testToUnsignedMaxInt64() public pure {
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(
+            type(int64).max
+        );
+        assertEq(value, uint64(type(int64).max));
+        assertEq(sign, 1);
+    }
+
+    function testToUnsignedFuzzPositive(int64 input) public pure {
+        vm.assume(input > 0);
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(input);
+        assertEq(value, uint64(input));
+        assertEq(sign, 1);
+    }
+
+    function testToUnsignedFuzzNegative(int64 input) public pure {
+        vm.assume(input < 0 && input != type(int64).min);
+        (uint64 value, int64 sign) = CombinePythPrice.toUnsigned(input);
+        assertEq(value, uint64(-input));
+        assertEq(sign, -1);
+    }
+
+    ////////////////////////////////
+    //           min()            //
+    ////////////////////////////////
+
+    function testMinBasicCase() public pure {
+        uint256 a = 100;
+        uint256 b = 200;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == a);
+    }
+
+    function testMinReversedOrder() public pure {
+        uint256 a = 200;
+        uint256 b = 100;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == b);
+    }
+
+    function testMinEqualValues() public pure {
+        uint256 a = 100;
+        uint256 b = 100;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == a);
+        assert(result == b);
+    }
+
+    function testMinZeroAndPositive() public pure {
+        uint256 a = 0;
+        uint256 b = 100;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == a);
+    }
+
+    function testMinPositiveAndZero() public pure {
+        uint256 a = 100;
+        uint256 b = 0;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == b);
+    }
+
+    function testMinLargeNumbers() public pure {
+        uint256 a = type(uint256).max;
+        uint256 b = type(uint256).max - 1;
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result == b);
+    }
+
+    function testMinFuzz(uint256 a, uint256 b) public pure {
+        uint256 result = CombinePythPrice.min(a, b);
+        assert(result <= a && result <= b);
+        assert(result == a || result == b);
+    }
+
+    function testMinWithTypicalTimestamps() public view {
+        uint256 currentTimestamp = block.timestamp;
+        uint256 futureTimestamp = currentTimestamp + 3600; // 1 hour in the future
+        uint256 result = CombinePythPrice.min(
+            currentTimestamp,
+            futureTimestamp
+        );
+        assert(result == currentTimestamp);
+    }
+
+    function testMinWithPastAndFutureTimestamps() public pure {
+        uint256 pastTimestamp = 1609459200; // 2021-01-01 00:00:00 UTC
+        uint256 futureTimestamp = 1735689600; // 2025-01-01 00:00:00 UTC
+        uint256 result = CombinePythPrice.min(pastTimestamp, futureTimestamp);
+        assert(result == pastTimestamp);
+    }
+
+    ////////////////////////////////
+    //    scaleToExponent()       //
+    ////////////////////////////////
+
+    function testScaleToExponentNoChange() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000,
+            conf: 10,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            -2
+        );
+        assert(result.price == 1000);
+        assert(result.conf == 10);
+        assert(result.expo == -2);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentScaleUp() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000,
+            conf: 10,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            0
+        );
+        assert(result.price == 10);
+        assert(result.conf == 0);
+        assert(result.expo == 0);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentScaleDown() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000,
+            conf: 10,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            -4
+        );
+        assert(result.price == 100000);
+        assert(result.conf == 1000);
+        assert(result.expo == -4);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentZeroPrice() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 0,
+            conf: 10,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            0
+        );
+        assert(result.price == 0);
+        assert(result.conf == 0);
+        assert(result.expo == 0);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentZeroConf() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000,
+            conf: 0,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            0
+        );
+        assert(result.price == 10);
+        assert(result.conf == 0);
+        assert(result.expo == 0);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentLargeScaleUp() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000000000,
+            conf: 10000000,
+            expo: -8,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            0
+        );
+        assert(result.price == 10);
+        assert(result.conf == 0);
+        assert(result.expo == 0);
+        assert(result.publishTime == 1625097600);
+    }
+
+    function testScaleToExponentLargeScaleDown() public {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 10,
+            conf: 1,
+            expo: 0,
+            publishTime: 1625097600
+        });
+
+        vm.expectRevert(CombinePythPrice.MathErrorWhileScaling.selector);
+        CombinePythPrice.scaleToExponent(price, -8);
+    }
+
+    function testScaleToExponentNegativePrice() public pure {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: -1000,
+            conf: 10,
+            expo: -2,
+            publishTime: 1625097600
+        });
+        PythStructs.Price memory result = CombinePythPrice.scaleToExponent(
+            price,
+            0
+        );
+        assert(result.price == -10);
+        assert(result.conf == 0);
+        assert(result.expo == 0);
+        assert(result.publishTime == 1625097600);
+    }
+
+    ///////////////////////////
+    //        Normalise()    //
+    ///////////////////////////
+
+    function testNormalizeNormalCase() public view {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1000000,
+            conf: 1000,
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.normalize(price);
+
+        assertEq(result.price, 1000000);
+        assertEq(result.conf, 1000);
+        assertEq(result.expo, -6);
+        assertEq(result.publishTime, price.publishTime);
+    }
+
+    function testNormalizeNegativePrice() public view {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: -1000000,
+            conf: 1000,
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.normalize(price);
+
+        assertEq(result.price, -1000000);
+        assertEq(result.conf, 1000);
+        assertEq(result.expo, -6);
+        assertEq(result.publishTime, price.publishTime);
+    }
+
+    function testNormalizeLargePrice() public {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 1_000_000_000_000_000_000,
+            conf: 1_000_000_000,
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+        CombinePythPrice.normalize(price);
+    }
+
+    function testNormalizeMinInt64() public {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: type(int64).min,
+            conf: 1000,
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+        CombinePythPrice.normalize(price);
+    }
+
+    function testNormalizeMaxUint64() public {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: type(int64).max,
+            conf: 1,
+            expo: 0,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+        CombinePythPrice.normalize(price);
+    }
+
+    function testNormalizeDivisionByZero() public {
+        PythStructs.Price memory price = PythStructs.Price({
+            price: 0,
+            conf: 0,
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+        CombinePythPrice.normalize(price);
+    }
+
+    ////////////////////////
+    //        div         //
+    ////////////////////////
+
+    function testDivNormalCase() public view {
+        PythStructs.Price memory price1 = PythStructs.Price({
+            price: 1000000000, // $1.00
+            conf: 10000000, // $0.01
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory price2 = PythStructs.Price({
+            price: 2000000000, // $2.00
+            conf: 20000000, // $0.02
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.div(price1, price2);
+
+        assertEq(result.price, 500000000); // 0.5
+        assertEq(result.conf, 10000000); // 0.0075
+        assertEq(result.expo, -9);
+    }
+
+    function testDivDifferentExponents() public view {
+        PythStructs.Price memory price1 = PythStructs.Price({
+            price: 1_000_000, // $1.00
+            conf: 10_000, // $0.01
+            expo: -6,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory price2 = PythStructs.Price({
+            price: 2_000_000_000, // $2.00
+            conf: 20_000_000, // $0.02
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.div(price1, price2);
+
+        assertEq(result.price, 5000000); // 0.5
+        assertEq(result.conf, 100000); // 0.0075
+        assertEq(result.expo, -7);
+    }
+
+    function testDivZeroDenominator() public {
+        PythStructs.Price memory price1 = PythStructs.Price({
+            price: 1000000000,
+            conf: 10000000,
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory price2 = PythStructs.Price({
+            price: 0,
+            conf: 20000000,
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+        CombinePythPrice.div(price1, price2);
+    }
+
+    function testDivLargeNumbers() public view {
+        PythStructs.Price memory price1 = PythStructs.Price({
+            price: 1000000000000000000, // 1e18
+            conf: 10000000000000000, // 1e16
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory price2 = PythStructs.Price({
+            price: 1000000000, // 1e9
+            conf: 10000000, // 1e7
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.div(price1, price2);
+
+        assertEq(result.price, 1000000000); // 1e9
+        assertEq(result.conf, 20000000); // 2e7
+        assertEq(result.expo, 0);
+    }
+
+    function testDivNegativeNumbers() public view {
+        PythStructs.Price memory price1 = PythStructs.Price({
+            price: -1000000000, // -$1.00
+            conf: 10000000, // $0.01
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory price2 = PythStructs.Price({
+            price: 2000000000, // $2.00
+            conf: 20000000, // $0.02
+            expo: -9,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.div(price1, price2);
+
+        assertEq(result.price, -500000000); // -0.5
+        assertEq(result.conf, 10000000); // 0.0075
+        assertEq(result.expo, -9);
+    }
+
+    ////////////////////////////////
+    //      getPriceInQuotes      //
+    ////////////////////////////////
+
+    function testGetPriceInQuote_SameExponent() public view {
+        PythStructs.Price memory basePrice = PythStructs.Price({
+            price: 100_000_000,
+            conf: 1_000_000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+        PythStructs.Price memory quotePrice = PythStructs.Price({
+            price: 50_000_000,
+            conf: 500_000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.getPriceInQuote(
+            basePrice,
+            quotePrice,
+            -9
+        );
+
+        PythStructs.Price memory nRes = CombinePythPrice.normalize(quotePrice);
+        console2.log("price", nRes.price);
+        console2.log("conf", nRes.conf);
+
+        assertEq(result.price, 2_000_000_000);
+        assertEq(result.conf, 40000000);
+        assertEq(result.expo, -9);
+    }
+
+    function testGetPriceInQuote_DifferentExponents() public view {
+        PythStructs.Price memory basePrice = PythStructs.Price({
+            price: 100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+        PythStructs.Price memory quotePrice = PythStructs.Price({
+            price: 5000000000,
+            conf: 50000000,
+            expo: -10,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.getPriceInQuote(
+            basePrice,
+            quotePrice,
+            -9
+        );
+
+        assertEq(result.price, 2000000000);
+        assertEq(result.conf, 40000000);
+        assertEq(result.expo, -9);
+    }
+
+    function testGetPriceInQuote_ZeroQuotePrice() public {
+        PythStructs.Price memory basePrice = PythStructs.Price({
+            price: 100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+        PythStructs.Price memory quotePrice = PythStructs.Price({
+            price: 0,
+            conf: 0,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+
+        vm.expectRevert(CombinePythPrice.DivisionByZero.selector);
+
+        CombinePythPrice.getPriceInQuote(basePrice, quotePrice, -9);
+    }
+
+    function testGetPriceInQuote_NegativePrices() public view {
+        PythStructs.Price memory basePrice = PythStructs.Price({
+            price: -100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+        PythStructs.Price memory quotePrice = PythStructs.Price({
+            price: -50000000,
+            conf: 500000,
+            expo: -8,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.getPriceInQuote(
+            basePrice,
+            quotePrice,
+            -9
+        );
+
+        assertEq(result.price, 2000000000);
+        assertEq(result.conf, 40000000);
+        assertEq(result.expo, -9);
+    }
+
+    function testGetPriceInQuote_LargeExponentDifference() public view {
+        PythStructs.Price memory basePrice = PythStructs.Price({
+            price: 100000000000000,
+            conf: 1000000000000,
+            expo: -14,
+            publishTime: block.timestamp
+        });
+        PythStructs.Price memory quotePrice = PythStructs.Price({
+            price: 5,
+            conf: 1,
+            expo: -1,
+            publishTime: block.timestamp
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.getPriceInQuote(
+            basePrice,
+            quotePrice,
+            -9
+        );
+
+        assertEq(result.price, 2000000000);
+        assertEq(result.conf, 420000000);
+        assertEq(result.expo, -9);
+    }
+
+    //////////////////////
+    //      addPrice    //
+    //////////////////////
+
+    function testAddPricesWithSameExponent() public pure {
+        PythStructs.Price memory p1 = PythStructs.Price({
+            price: 100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: 1625097600
+        });
+
+        PythStructs.Price memory p2 = PythStructs.Price({
+            price: 200000000,
+            conf: 2000000,
+            expo: -8,
+            publishTime: 1625097700
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.addPrices(p1, p2);
+
+        assertEq(result.price, 300000000);
+        assertEq(result.conf, 3000000);
+        assertEq(result.expo, -8);
+        assertEq(result.publishTime, 1625097600);
+    }
+
+    function testAddPricesWithNegativeValues() public pure {
+        PythStructs.Price memory p1 = PythStructs.Price({
+            price: -100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: 1625097600
+        });
+
+        PythStructs.Price memory p2 = PythStructs.Price({
+            price: 200000000,
+            conf: 2000000,
+            expo: -8,
+            publishTime: 1625097700
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.addPrices(p1, p2);
+
+        assertEq(result.price, 100000000);
+        assertEq(result.conf, 3000000);
+        assertEq(result.expo, -8);
+        assertEq(result.publishTime, 1625097600);
+    }
+
+    function testAddPricesWithZeroValues() public pure {
+        PythStructs.Price memory p1 = PythStructs.Price({
+            price: 0,
+            conf: 0,
+            expo: -8,
+            publishTime: 1625097600
+        });
+
+        PythStructs.Price memory p2 = PythStructs.Price({
+            price: 200000000,
+            conf: 2000000,
+            expo: -8,
+            publishTime: 1625097700
+        });
+
+        PythStructs.Price memory result = CombinePythPrice.addPrices(p1, p2);
+
+        assertEq(result.price, 200000000);
+        assertEq(result.conf, 2000000);
+        assertEq(result.expo, -8);
+        assertEq(result.publishTime, 1625097600);
+    }
+
+    function testAddPricesWithDifferentExponents() public {
+        PythStructs.Price memory p1 = PythStructs.Price({
+            price: 100000000,
+            conf: 1000000,
+            expo: -8,
+            publishTime: 1625097600
+        });
+
+        PythStructs.Price memory p2 = PythStructs.Price({
+            price: 200000000,
+            conf: 2000000,
+            expo: -9,
+            publishTime: 1625097700
+        });
+
+        vm.expectRevert(
+            abi.encodeWithSelector(
+                CombinePythPrice.AddingPricesOfDifferentExponents.selector,
+                -8,
+                -9
+            )
+        );
+        CombinePythPrice.addPrices(p1, p2);
+    }
+}
diff --git a/target_chains/ethereum/sdk/solidity/abis/CombinePythPrice.abi b/target_chains/ethereum/sdk/solidity/abis/CombinePythPrice.abi
new file mode 100644
index 0000000000..fd36337618
--- /dev/null
+++ b/target_chains/ethereum/sdk/solidity/abis/CombinePythPrice.abi
@@ -0,0 +1,218 @@
+[
+  {
+    "type": "function",
+    "name": "div",
+    "inputs": [
+      {
+        "name": "self",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      },
+      {
+        "name": "other",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      }
+    ],
+    "outputs": [
+      {
+        "name": "result",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      }
+    ],
+    "stateMutability": "pure"
+  },
+  {
+    "type": "function",
+    "name": "getPriceInQuote",
+    "inputs": [
+      {
+        "name": "self",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      },
+      {
+        "name": "quote",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      },
+      {
+        "name": "targetExpo",
+        "type": "int32",
+        "internalType": "int32"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "result",
+        "type": "tuple",
+        "internalType": "struct PythStructs.Price",
+        "components": [
+          {
+            "name": "price",
+            "type": "int64",
+            "internalType": "int64"
+          },
+          {
+            "name": "conf",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "expo",
+            "type": "int32",
+            "internalType": "int32"
+          },
+          {
+            "name": "publishTime",
+            "type": "uint256",
+            "internalType": "uint256"
+          }
+        ]
+      }
+    ],
+    "stateMutability": "pure"
+  },
+  {
+    "type": "error",
+    "name": "AddingPricesOfDifferentExponents",
+    "inputs": [
+      {
+        "name": "expo1",
+        "type": "int32",
+        "internalType": "int32"
+      },
+      {
+        "name": "expo2",
+        "type": "int32",
+        "internalType": "int32"
+      }
+    ]
+  },
+  {
+    "type": "error",
+    "name": "DivisionByZero",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "ExceedingComputationalRange",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "MathErrorWhileScaling",
+    "inputs": []
+  }
+]