CFrame lerping not working as intended?

So currently I’m trying to lerp a CFrame C0 between 2 CFrames for an Aim Down Sight System.

I’ve already calculated the offset between the Aim Part in the tool and the center of the camera.
offsetx, offsety, offsetz determines the offset, in vector3.
I lerp the Tool, Left Arm and Right Arm independently, they’re inside a ViewModel.

This is what I did without lerping, ignore the order of XYZ values

						char.Torso.ToolGrip.C0 = char.Torso.ToolGrip.C0 * CFrame.new(offsetX,offsetY,offsetZ)
						ViewModelTorso["Left Shoulder"].C0 = ViewModelTorso["Left Shoulder"].C0 * CFrame.new(offsetZ,offsetY,-offsetX)
						ViewModelTorso["Right Shoulder"].C0 = ViewModelTorso["Right Shoulder"].C0 *CFrame.new(-offsetZ,offsetY,offsetX)

This is the result with no lerping (code above), you can see the arms positioned correctly.
https://gyazo.com/0f549d0c85da57a0e19a7220c6905662

When I lerp the Tool, it works as intended.

						delay(0,function()
							for i = 0,1,0.05 do
								char.Torso.ToolGrip.C0 = char.Torso.ToolGrip.C0:lerp(CFrame.new(offsetX,offsetY,offsetZ),i)
								wait()
							end
						end)

However, it doesn’t work for the Left Arm and Right Arm. The ViewModel Rig is copied from the Roblox’s default R6 Rig.

						delay(0,function()
							for i = 0,1,0.05 do
								char.Torso.ToolGrip.C0 = char.Torso.ToolGrip.C0:lerp(CFrame.new(offsetX,offsetY,offsetZ),i)
								wait()
							end
						end)
						
						delay(0,function()
							for i = 0,1,0.05 do
								ViewModelTorso["Left Shoulder"].C0 = ViewModelTorso["Left Shoulder"].C0:lerp(CFrame.new(offsetZ,offsetY,-offsetX),i)
								wait()
							end
						end)
					
						delay(0,function()
							for i = 0,1,0.05 do
								ViewModelTorso["Right Shoulder"].C0 = ViewModelTorso["Right Shoulder"].C0:lerp(CFrame.new(-offsetZ,offsetY,offsetX),i)
								wait()
							end
						end)

This is the result, you can see Left Arm and Right Arm positioned wrong, but the tool positioned as intended.
https://gyazo.com/73a6abce8426988e167eed061d1ee4e9

How do I fix this? I just implemented lerping, nothing else though?

Try getting the old offset of the arms and using that to lerp to the intended CFrame:

-- for both shoulders, where each one is `ViewModelTorso["_ Shoulder"]

delay(0, function()
	local oldCFrame = shoulder.C0
	for i = 0, 1, 0.05 do
		shoulder.C0 = shoulder.C0:Lerp(oldCFrame * CFrame.new(-offsetZ, offsetY, offsetX), i)
		wait()
	end
end)
Getting a smoother lerp:

You can also make the lerp smoother using RunService.RenderStepped or just RunService.Stepped:

local RunService = game:GetService("RunService")

locla duration = 1 -- how long lerp should last, in seconds

local startCFrame = shoulder.C0 -- where the shoulder starts
local goalCFrame = shoulder.C0 * offset -- where the shoulder stops

-- start value of tween
local i = 0 

-- create an asynchronous loop
coroutine.wrap(function()
	while i < 1 do -- until the tween is finished,
		-- get time elapsed
		local dt = RunService.RenderStepped:Wait() 

		-- increment i by time elapsed of duration
		-- this also clamps i's value to a maximum of 1
		i = math.min(i + dt/duration, 1) 
		
		-- lerp shoulder
		shoulder.C0 = startCFrame:Lerp(goalCFrame, i)
	end
end)()

And you can make a custom tweening style using TweenService:GetValue:

local TweenService = game:GetService("TweenService")

-- modified excerpt from above,
local i = 0
coroutine.wrap(function()
	while i < 1 do
		local dt = RunService.RenderStepped:Wait()
		
		i = math.min(i + dt/duration, 1)
		
		-- get value transformed over tween curve
		local a = TweenService:GetValue( 
			i, 
			Enum.EasingStyle.Quad,
			Enum.EasingDirection.Out
		)
		
		-- lerp shoulder
		shoulder.C0 = startCFrame:Lerp(goalCFrame, a)
	end
end)()